精华内容
下载资源
问答
  • Swift2.0语言教程之函数的返回值与函数类型Swift2.0中函数的返回值根据是否具有返回值,函数可以分为无返回值函数和有返回值函数。以下将会对这两种函数类型进行讲解。Swift2.0中具有一个返回值的函数开发者希望...

    Swift2.0语言教程之函数的返回值与函数类型

    Swift2.0中函数的返回值

    根据是否具有返回值,函数可以分为无返回值函数和有返回值函数。以下将会对这两种函数类型进行讲解。

    Swift2.0中具有一个返回值的函数

    开发者希望在函数中返回某一数据类型的值,必须要在函数声明定义时为函数设定一个返回的数据类型,并使用return语句进行返回。其中,return语句的一般表示形式如下:

    return 表达式

    其中,表达式可以是符合Swift标准的任意表达式。而具有返回值的函数声明定义形式如下:

    func 函数名(参数列表)->返回值类型{

    语句

    return 表达式

    }

    其中,返回的表达式类型必须和函数的返回值类型一致。

    【示例7-13】以下代码计算某一数值范围的长度,并返回输出。代码如下:

    import Foundation

    func range(start:Int,end:Int)->Int{

    return end-start

    }

    let a=range(0, end: 10)

    print(a)

    在代码中,指定函数的返回值类型为Int,而return表达式为end-start。运行结果如下所示:

    10

    Swift2.0中具有多个返回值的函数

    在Swift中,函数不仅可以返回一个返回值,还可以返回多个,这时就需要使用到元组类型。其语法形式如下:

    func count(参数列表) -> (返回值1:数据类型,返回值2:数据类型,返回值3:数据类型,…){

    ……

    return (返回值1,返回值2,返回值3,…)

    }

    【示例7-14】下面就获取在一个字符串中得元音、辅音以及其它的个数。代码如下:

    import Foundation

    func count(string: String) -> (vowels: Int, consonants: Int, others: Int){

    var vowels = 0, consonants = 0, others = 0

    for character in string.characters  {

    switch String(character).lowercaseString {

    case "a", "e", "i", "o", "u":

    ++vowels

    case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",

    "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":

    ++consonants

    default:

    ++others

    }

    }

    return (vowels, consonants, others)

    }

    let str="Hello Swift!"

    let number=count(str)

    print("\(number.vowels)元音\n\(number.consonants)辅音\n\(number.others)其它")

    运行结果如下所示:

    3元音

    7辅音

    2其它

    在具有多个返回值的函数需要注意以下2点:

    1.返回值个数一致

    在->后面的返回值类型的个数要和return中的返回值个数一致,否则程序就会出现错误。如以下的代码,将示例7-14中的代码做了修改:

    func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {

    var vowels = 0, consonants = 0, others = 0

    return (vowels, consonants)

    }

    在此代码中可以知道,->后面的返回值类型有3个,但是return中得返回值有2个,它们的个数不一样,导致程序出现以下的错误:

    Tuple types '(@lvalue Int, @lvalue Int)' and '(vowels: Int, consonants: Int, others: Int)' have a different number of elements (2 vs. 3)

    2.返回值顺序

    在->后面的返回值类型要和return中的返回值类型的顺序一致,否则程序就会出现错误。如以下的代码,将示例7-14中的代码做了修改:

    func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {

    var vowels = 0, consonants = 0, others = 0

    return (vowels,others,consonants)

    }

    在此代码中,->后面的返回值为(vowels: Int, consonants: Int, others: Int),return中的返回值为(vowels,others,consonants)由于它们的数据类型相同都是整型,所以在改变它们的位置后,程序不会出现错误。运行结构如下:

    3元音

    2辅音

    7其它

    Swift2.0中无返回值

    函数除了有有返回值类型外,还有没有返回值的类型。在第7.2、7.3、7.4节中所讲的都是没有返回值的函数类型。没有返回值的类型不需要定义返回值类型,并且也不需要出现return语句。如果出现return语句,反而会造成程序错误。例如以下的代码,它的功能是输出某一数字。

    import Foundation

    func printaa(a:Int){

    return a

    }

    let num=9

    let number=printaa(num)

    print(number)

    在此函数中,它是没有返回值的,但是在函数中又使用了renturn语句返回了a的值,所以导致程序出现了以下的错误信息:

    'Int' is not convertible to '()'

    Swift2.0中函数类型

    在Swift中,每一个函数都是一个特定的类型,这种类型被称为函数类型。它由参数类型和返回值类型构成。例如以下代码就是一个具有参数类型和返回值类型的函数:

    func add(a: Int, b: Int) -> Int {

    return a + b

    }

    在该代码中,定义了一个实现加法运算的数学函数add。此函数接受了两个Int整型的参数,执行相应的数学运算后,返回一个Int整型值作为结果。这个函数的类型就是(Int,Int)->Int,程序员可以理解为函数类型有两个Int整型参数,并返回一个Int整型值。在Swift除了有具有参数列表和返回值类型的函数外,还有不带参数和返回值类型的函数,如以下代码是一个不带参数和返回值的函数:

    func printHelloWorld(){

    print("Hello,World")

    }

    函数printHelloWorld()的类型是()->()。由于函数没有参数,返回void,所以该类型在Swift中相当于一个空元组,也可以简化为()。

    Swift2.0中使用函数类型

    作为一种类型,程序员可以像任何其他类型一样使用函数类型。基本语法如下:

    let/var 常量名/变量名:函数类型=函数名

    或者

    let/var 常量名/变量名=函数名

    【示例7-15】以下将使用一个mathFunction变量引用函数add。代码如下:

    import Foundation

    func add(a: Int, b: Int) -> Int {

    return a + b

    }

    var mathFunction: (Int, Int) -> Int = add

    print(mathFunction(2,8))

    在代码中定义了一个mathFunction变量,并将该变量的类型设定为函数类型。它接受了两个Int整型值,并返回了一个Int整型值。使用这个新的变量mathFunction来引用add函数的功能。运行结果如下所示:

    10

    由于Swift具有自动推断类型的能力,所以可以在声明变量后直接赋值,不需要单个为变量去声明类型,所以以上的为变量赋值的代码可以改写为:

    var mathFunction = add

    如果不同函数具有相同的函数类型,这时把它们赋值给同一个变量。例如,在以上的代码中在添加一个函数:

    func multiply(a:Int,b:Int)->Int{

    return a*b

    }

    由于mathFunction变量和multiply的类型匹配,所以可以直接赋值,并输出,代码如下:

    mathFunction=multiply

    print(mathFunction(3,8))

    代码如下所示:

    10

    24

    Swift2.0中使用函数类型作为参数类型

    开发者可以使用函数类型作为另一个函数的参数类型。例如以下代码,它的功能是让个数进行相加或者相乘,然后输出。代码如下:

    import Foundation

    //两数相加

    func add(a: Int, b: Int) -> Int {

    return a + b

    }

    //两数相乘

    func multiply(a:Int,b:Int)->Int{

    return a*b

    }

    //输出结果

    func printresult(fun:(Int,Int)->Int,a:Int,b:Int){

    print(fun(a,b))

    }

    printresult(add, a: 3, b: 2)

    printresult(multiply, a: 3, b: 2)

    在此代码中定义了三个函数。第三个函数printresult中,有三个参数:第一个参数为fun,类型为(Int,Int)->Int,开发者可以传入任何这种类型的函数;第二个参数和第三个参数分别为a和b,它们的类型都是Int型,这两个值是函数的输入值。当第一次调用printresult函数时,它传入了add函数和3、5两个整数。这时,它又会调用函数add,将3、5作为函数add的输入值,并输出结果。第二此调用也类似,printresult会调用multiply函数。最后的运行结果如下所示:

    5

    6

    Swift2.0中使用函数类型作为返回值类型

    函数类型不仅可以被用作参数外,还可以被用作返回值类型。此时需要在->后面写入一个完整的函数类型,其语法形式如下:

    func 函数名(参数列表) -> 函数类型 {

    }

    【示例7-16】以下代码输出通过给定的值,出现一系列的值;如果给定的值大于0输出从这个数开始到0之间的数;如果是负数,一直输出比这个是小1的数。代码如下:

    import Foundation

    //返回一个比输入值大1得值

    func stepForward(input: Int) -> Int {

    return input + 1

    }

    //返回一个比输入值小1得值

    func stepBackward(input: Int) -> Int {

    return input - 1

    }

    //选择返回哪个函数

    func chooseStepFunction(backwards: Bool) -> (Int) -> Int {

    return backwards ? stepBackward : stepForward

    }

    var currentValue = 5

    let moveNearerToZero = chooseStepFunction(currentValue>0)

    while currentValue != 0 {

    print("\(currentValue)... ")

    currentValue = moveNearerToZero(currentValue)

    }

    在此代码中定义了3个函数。第三个函数chooseStepFunction的返回值类型是(Int)->Int。运行结果如下所示:

    5...

    4...

    3...

    2...

    1...

    Swift2.0中的标准函数

    函数除了可以根据参数列表的有无分为无参函数和有参函数,还可以从定义角度分为用户自定义函数和标准函数两种。以上的示例都是用户自定函数。Swift提供了74个标准函数,这些函数都可以直接去使用,不需要进行定义。本节将针对常用的标准函数进行详细的讲解。

    Swift2.0中绝对值函数abs()

    abs()函数的功能是求数值的绝对值。其语法形式如下:

    abs(数值)

    函数的返回值是一个零或者正数。

    【示例7-17】以下将使用abs()函数获取-10、10、0、-1.233、1.233的绝对值。代码如下:

    import Foundation

    //求整数的绝对值

    let value1=abs(-10)

    let value2=abs(10)

    let value3=abs(0)

    //求浮点数的绝对值

    let value4=abs(-1.233)

    let value5=abs(1.233)

    print("value1=\(value1)")

    print("value2=\(value2)")

    print("value3=\(value3)")

    print("value4=\(value4)")

    print("value5=\(value5)")

    在此代码中,正数的绝对值是它本身;负数的绝对值为正数;0的绝对值还为0。运行结果如下:

    value1=10

    value2=10

    value3=0

    value4=1.233

    value5=1.233

    注意:abs()中的参数必须是数值,不可以是数值以外的东西,如字符、字符串等。如以下的代码,将获取字符串"aaa"的绝对值。代码如下:

    import Foundation

    let value1=abs("aaa")

    print("value1=\(value1)")

    由于abs()的参数为字符串导致程序出现了以下错误:

    Cannot find an overload for 'abs' that accepts an argument list of type '(String)'

    Swift2.0中最大值函数max()/最小值min()

    在编程中,经常需要计算几个参数的最大值或者最小值,此时可以使用标准函数中的max()和min()函数实现。以下是对这两个函数的详细讲解。

    1.获取最大值

    max()函数可以获取几个参数的最大值。其语法形式如下:

    max(参数1,参数2,参数3,…)

    其中,参数可以是数值,也可以是字符串或字符。

    【示例7-18】以下将使用max()函数,依次获取1.9和10的最大值,13.8、20、88.88的最大值以及字符串"Hello"、"Swift"、"Zone"的最大值。代码如下:

    import Foundation

    let maxValue1=max(1.9,10)

    let maxValue2=max(13.8,20,88.88)

    let maxValue3=max("Hello","Swift","Zone")

    print("maxValue1=\(maxValue1)")

    print("maxValue2=\(maxValue2)")

    print("maxValue3=\(maxValue3)")

    在对字符串进行比较时,是对字符串中的字符进行比较。首先会判断3个字符的首字符哪个大。如果找到最大的字符,就以此字符开头的字符串为最大值;如果判断的3个首字符相同,那么在进行第二个字符的比较,以此类推。运行结果如下:

    maxValue1=10.0

    maxValue2=88.88

    maxValue3=Zone

    2.获取最小值

    min()函数可以获取几个参数的最小值。其语法形式如下:

    min(参数1,参数2,参数3,…)

    其中,参数同样可以是数值、字符串或字符。

    【示例7-19】以下将使用min()函数,获取1.9和10的最小值,获取13.8、20、88.88的最小值,字符串"Swift"、"Hello"、"iOS"的最小值。代码如下:

    import Foundation

    let minValue1=min(1.9,10)

    let minValue2=min(13.8,20,88.88)

    let minValue3=min("Swift","Hello","iOS")

    print("minValue1=\(minValue1)")

    print("minValue2=\(minValue2)")

    print("minValue3=\(minValue3)")

    运行结果如下:

    minValue1=1.9

    minValue2=13.8

    minValue3=Hello

    注意:在使用max()、min()时如果是数值,比较的参数都是数值。如果是字符或者字符串,比较的参数也是字符或者字符串。不可以在一个函数中同时比较数值和字符串、字符。以下的代码将比较1.9、10和字符串"Hello"的最小值。代码如下:

    import Foundation

    let minValue=min(1.9,10,"Hello")

    println("minValue=\(minValue)")

    在此代码中,由于min()函数对数值和字符串进行比较,导致程序出现了以下的错误:

    Cannot find an overload for 'min' that accepts an argument list of type '(Double, Int, String)'

    Swift2.0中序列的最大值函数maxElement()/最小值函数minElement()

    在一个序列中,往往需要获取元素的最大值或者最小值。此时可以使用maxElement()和minElement()函数。以下是对这两个函数的详细讲解。

    1.序列的最大值

    maxElement()函数获取一个序列中最大值的元素。其语法形式如下:

    序列.maxElement()

    其中,序列可以是数值,也可以是一个范围。

    【示例7-20】下面使用maxElement()函数获取序列sequence1、sequence2和范围1...100中最大值的元素。代码如下:

    import Foundation

    let sequence1=[9,8,2,3]

    let sequence2=["Ad","Ab","Ac"]

    let maxValue1=sequence1.maxElement()!

    print("maxValue1=\(maxValue1)")

    let maxValue2=(1...100).maxElement()!

    print("maxValue2=\(maxValue2)")

    let maxValue3=sequence2.maxElement()!

    print("maxValue3=\(maxValue3)")

    其中,字符串构成的序列sequence2的判断方式与函数max()相同,都是依次比较字符串的字母大小。运行结果如下:

    maxValue1=9

    maxValue2=100

    maxValue3=Ad

    2.序列的最小值

    minElement()函数可以获取一个序列中最小值的元素。其语法形式如下:

    序列.minElement()

    其中,序列可以是数值,也可以是一个范围。

    【示例7-21】以下将使用minElement()函数获取序列sequence1、sequence2和范围1...100中最小值的元素。代码如下:

    import Foundation

    let sequence1=[9,8,2,3]

    let sequence2=["Ad","Ab","Ac"]

    let minValue1=sequence1.minElement()!

    print("minValue1=\(minValue1)")

    let minValue2=(1...100).minElement()!

    print("minValue2=\(minValue2)")

    let minValue3=sequence2.minElement()!

    print("minValue3=\(minValue3)")

    运行结果如下:

    minValue1=2

    minValue2=1

    minValue3=Ab

    Swift2.0中判断序列是否包含指定元素函数contains()

    contains()函数可以判断一个序列中是否包含指定的元素。其语法形式如下:

    序列.contains(元素)

    其中,函数的返回值类型为布尔类型。当返回true时,表示表达序列中包含指定的元素;当返回false时,表示不包含。

    【示例7-22】以下代码使用contains()函数函数判断序列languages中是否包含元素"Swift"和"Java"。代码如下:

    import Foundation

    var languages = ["Swift", "Objective-C","C"]

    //判断在languages数组中是否包含"Swift"字符串

    if languages.contains("Swift") == true  {

    print("languages序列中包含元素“Swift”")

    }else{

    print("languages序列中不包含元素“Swift”")

    }

    //判断在languages数组中是否包含"Java"字符串

    if languages.contains("Java") == true  {

    print("languages序列中包含元素“Java”")

    }else{

    print("languages序列中不包含元素“Java”")

    }

    在此代码languages中"Swift"、"Objective-C"、"C"这三个元素,但是没有"Java"元素。运行结果如下:

    languages序列中包含元素“Swift”

    languages序列中不包含元素“Java”

    在比较的时候,会区分字母的大小写。所以,不同大小写的字符串是不同的。

    Swift2.0序列排序函数sortInPlace()

    在编程中,经常需要对序列中元素的进行排序。此时可以使用Swift中的sortInPlace()函数来实现。其语法形式如下:

    序列.sortInPlace()

    其中,序列是指数组。

    【示例7-23】以下将使用sort()函数对languages和value数组进行排序。代码如下:

    import Foundation

    var languages = ["Swift", "Objective-C","C"]

    print("排序前:languages=\(languages)")

    languages.sortInPlace()

    print("排序后:languages=\(languages)")

    运行结果如下:

    排序前:languages=[Swift, Objective-C, C]

    排序后:languages=[C, Objective-C, Swift]

    Swift2.0序列倒序函数reverse()

    reverse()函数可以将序列中元素的倒序排列。其语法形式如下:

    序列.reverse()

    其中,序列是指数组。

    【示例7-24】以下将使用reverse 函数对序列languages和value进行倒序排列。代码如下:

    import Foundation

    var languages = ["Swift", "Objective-C","C"]

    print("languages=\(languages)")

    print("倒序输出:")

    for i in Array(languages.reverse()){

    print(i)

    }

    var value = [1,8,4,10]

    print("value=\(value)")

    print("倒序输出:")

    for i in Array(value.reverse()){

    print(i)

    }

    运行结果如下:

    languages=[Swift, Objective-C, C]

    倒序输出:

    C

    Objective-C

    Swift

    value=[1, 8, 4, 10]

    倒序输出:

    10

    4

    8

    1

    本文选自:Swift2.0语言快速入门v3.0 大学霸内部资料,转载请注明出处,尊重技术尊重IT人!

    展开全文
  • 通常我们希望通过函数调用使主调函数能得到一个确定的值,这就是函数的...return 语句中表达式的类型定义函数时指定的返回值类型一致。如果不一致,则以函数定义时的返回值类型为准,对 return 语句中表达式...
    5de8d123d31547a13135759090721ffe.png

    通常我们希望通过函数调用使主调函数能得到一个确定的值,这就是函数的返回值

    函数的返回值是通过函数中的 return 语句获得的。return 语句将被调函数中的一个确定的值带回到主调函数中,供主调函数使用。

    一、类型一致

    函数的返回值类型是在定义函数时指定的。return 语句中表达式的类型应与定义函数时指定的返回值类型一致。如果不一致,则以函数定义时的返回值类型为准,对 return 语句中表达式的类型自动进行转换,然后再将它返回给主调函数使用。

    测试代码:

    // 定义类型与实际返回类型一致int test1(){  return 0;}// 定义类型与实际返回类型不同int test2(){  return 1.0;}

    运行结果:

    警告  C4244  “return”: 从“double”转换到“int”,可能丢失数据

    二、多个return

    一个函数中可以有多个 return 语句,但并不是所有的 return 语句都起作用。执行到哪个 return 语句,就是哪个 return 语句起作用,该 return 语句后的其他语句就都不会执行了。

    测试代码:

    int test1(int stat){    if(stat == 0)        return 0;    else if(stat == 1)        return 1;    else if(stat == 1)        return 1;    else        return 1;}

    三、return如何将值返回给主调函数

    被调函数运行结束后系统为被调函数中的局部变量分配的内存空间就会被释放。return 返回的那个值在被调函数运行一结束就被释放掉了,那么它是怎么返回给主调函数的呢?

    在执行 return 语句时系统是在内部自动创建了一个临时变量,然后将 return 要返回的那个值赋给这个临时变量。所以当被调函数运行结束后 return 后面的返回值真的就被释放掉了,最后是通过这个临时变量将值返回给主调函数的。

    而且定义函数时指定的返回值类型实际上指定的就是这个临时变量的类型

    四、指针作为函数返回值

    用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。

    测试代码:

    #include int *func(){    int n = 100;    return &n;}int main(){    int *p = func(), n;    n = *p;    printf("value = %d", n);    return 0;}

    运行结果:

    value = 100

    分析

    n 是 func() 内部的局部变量,func() 返回了指向 n 的指针,func() 运行结束后 n 将被销毁,使用 *p 应该获取不到 n 的值。

    但是,这里所谓的销毁并不是将局部数据所占用的内存全部抹掉,而是程序放弃对它的使用权限,弃之不理,后面的代码可以随意使用这块内存。如果有其它函数被调用就会覆盖这块内存,得到的数据就失去了意义。

    C 语言不支持在调用函数时返回局部变量的地址,除非定义局部变量为 static 变量

    五、函数中返回字符串指针

    错误代码:

    char* getString(){    char str[20] = "TEST";    return str;}

    分析

    理由见第“四”条

    正确代码:

    char* getString(){    char *p = "TEST";    return p;}

    分析:

    在函数内部定义了一个指向char类型的指针p,该指针指向一个字符串常量"TEST",而它存放在整个程序的常量区,而并不是局部变量,并不会因为函数调用的结束而消失。

    对于指针变量p虽然是一个局部变量,但p本身的值仅仅是一个4个字节的指针地址值。

    展开全文
  • 函数与lambda表达式

    2020-08-02 22:37:16
    函数lambda表达式 ...函数文档是是对函数作用的解释, 可以这里说明函数的使用方式和参数类型, 返回值类型 2. 函数参数 python支持多种参数类型 位置参数 (positional argument) 默认参数 (default argumen

    函数与lambda表达式

    函数

    函数的定义

    语法:

    def 函数名(参数列表):
        """
        函数文档
        :param 参数: 参数说明
        :return: 返回值说明
        """
        代码块
        [return [返回值]]
    

    1. 函数文档

    函数文档是是对函数作用的解释, 可以在这里说明函数的使用方式和参数类型, 返回值类型

    2. 函数参数

    python支持多种参数类型

    1. 位置参数 (positional argument)
    2. 默认参数 (default argument)
    3. 可变参数 (variable argument)
    4. 关键字参数 (keyword argument)
    5. 命名关键字参数 (name keyword argument)
    6. 参数组合
    1. 位置参数

    位置参数根据先后顺序确定传入的值, 是python最基本的传参方式

    2. 默认参数

    可以给参数默认值, 默认参数可以在调用时不传递参数, 这样会使用默认值, 但是如果函数参数列表里既有位置参数, 又有默认参数, 那么默认参数必须放到位置参数之后

    3. 可变参数
    def my_print(arg1, *args):
        print(args)
    
    
    print(1, 2, 3, 4, 5)  # (2,3,4,5)
    

    可见args将后面的参数封装为一个元组可以使用元组调用传入参数, 可变参数也必须放在位置参数之后

    4. 关键字参数
    def functionname(arg1, arg2=v, *args, **kw):
        "函数_文档字符串"
        print(kw)  
    
    
    functionname(1, 2, 3, a=1, b=2)  # {'a': 1, 'b': 2}
    

    可见kw将关键字参数封装入一个字典, 可以通过字典访问关键字参数

    5. 命名关键字参数
    def functionname(arg1, arg2=v, *args, *, nkw, **kw):
        "函数_文档字符串"
        function_suite
        return [expression]
    
    • *, nkw - 命名关键字参数,用户想要输入的关键字参数,定义方式是在nkw 前面加个分隔符 *。
    • 如果要限制关键字参数的名字,就可以用「命名关键字参数」
    • 使用命名关键字参数时,要特别注意不能缺少参数名。
    6. 参数组合

    在 Python 中定义函数,可以用位置参数、默认参数、可变参数、命名关键字参数和关键字参数,这 5 种参数中的 4 个都可以一起使用,但是注意,参数定义的顺序必须是:

    • 位置参数、默认参数、可变参数和关键字参数。
    • 位置参数、默认参数、命名关键字参数和关键字参数。

    虽然可以定义多种参数, 但为了易于阅读, 尽量不要使用太多组合

    函数返回值

    函数返回值可以返回任意类型数据, int, string, 列表, 集合, 甚至是函数

    变量作用域

    • 定义在函数外边的变量称为全局变量, 在函数里边可以访问
    • 定义在函数里边的变量称为局部变量, 在函数外边无法访问
    • 同名局部变量可以覆盖全局变量, 在离开函数后解除变量覆盖, 如果在函数内部修改全局变量, 需要使用global关键字
    内嵌函数
    def outer():
        print('outer函数在这被调用')
    
        def inner():
            print('inner函数在这被调用')
    
        inner()  # 该函数只能在outer函数内部被调用
    
    
    outer()
    # outer函数在这被调用
    # inner函数在这被调用
    
    闭包
    • 是函数式编程的一个重要的语法结构,是一种特殊的内嵌函数。
    • 如果在一个内部函数里对外层非全局作用域的变量进行引用,那么内部函数就被认为是闭包。
    • 通过闭包可以访问外层非全局作用域的变量,这个作用域称为 闭包作用域。
    • 如果想要修改闭包外函数作用域的参数, 可以使用nonlocal关键字
    递归

    可以在一个函数的内部调用该函数

    def fun(x):
        if x == 1:
            return 1
        else:
            return fun(x - 1)
    

    lambda表达式

    匿名函数

    可以使用lambda表达式定义匿名函数

    lambda 参数列表: 表达式
    
    • 表达式里不需要return语句, 因为lambda的结果会作为返回值
    • 匿名函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。

    匿名函数的应用

    匿名函数 常常应用于函数式编程的高阶函数 (high-order function)中,主要有两种形式:

    • 参数是函数 (filter, map)
    • 返回值是函数 (closure)
      例如:
    odd = lambda x: x % 2 == 1
    templist = filter(odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
    print(list(templist))  # [1, 3, 5, 7, 9]
    

    练习题

    def 函数名(参数列表):
        """
        函数文档
        :param 参数: 参数类型
        :return: 返回值类型
        """
    
    1. 使用nonlocal关键字
    def sort(fun, list):
        """
        :param fun: function
        :param list:  list
        :return: sotred list
        """
        return fun(list)
    
    def move(x):
        """
        移动64个圆盘相当于将63个圆盘移到b柱再将第64个圆盘移到c柱, 这样问题化解为将63个圆盘从b柱移到c柱, 一次向下化简问题因此可以利用函数递归实现
        :param x: int
        :return: int
        """
        if x == 1:
            return 1
        else:
            return 2*move(x - 1) + 1
        
    
    print(move(64))
    
    
    展开全文
  • 一 引入函数类型在初中阶段就接触到了: 就是一个以实数为定义域陪域(值域有一些区别)的函数。二 函数类型如果 是类型,那么 也是一个类型。记作: 。如何构造这样一个类型的元素呢?给定一个表达式 ,其中...

    3cbd52a229f8f6efd6277fd9689237eb.png

    一 引入

    函数类型在初中阶段就接触到了:

    就是一个以实数为定义域与陪域(与值域有一些区别)的函数。

    二 函数类型

    如果

    是类型,那么
    也是一个类型。记作:

    如何构造这样一个类型的元素呢?给定一个表达式

    ,其中如果
    那么
    。由这个表达式就可以构造一个函数

    那么

    。这里
    是沿袭HoTT书[1]中的记号,代表“根据定义,前者就是后者”;也就是说,可以在任意地方将式子的左右侧互换。这会在相等类型的讨论中进一步解释。

    另一种写法就是

    -抽象:

    (其中

    可以省略为
    )。这种写法比较干净,可以迅速地临时引入一个函数,而不必在前面先说明(至于为什么用这个字母,是因为Church本来想写
    ,但是印刷技术不行,印成了
    ,后来就演化成
    )。在各大语言中都有对应物,比如Python的
    lambda关键字、JS的箭头函数。其中,后者更接近于我们要引入的第三种记法:

    注意两个箭头的不同写法。在HoTT书[1]中还有一种记法,就是将函数的自变量写作“

    ”,举个例子,
    就是
    的简记法。作为一个语法糖还是不错的。

    上面讲了构造,那么我们如何使用一个已经构造好的元素呢?举个例子,如果

    ,我们就有
    。也就是说,如果
    ,那么
    就是
    中所有
    都替换成
    ,写作
    。这个称为
    代入(application)。

    其实这里有一些命名上的细枝末节。譬如

    ,那么
    。这一点的处理,可以参见[1]的相关部分与[2]的讨论。

    对于任何一个函数

    ,我们都可以构造一个函数
    。我们可以认为这个函数跟原来那个是完全一样的:

    这个称作

    -化简。在讲外延相等与内蕴相等的时候(也在相等类型那一节)会详细阐述。这里
    代表“虽然不是根据定义,但是两者完全相同,可以随意互换”。

    最后,讲讲如何巧妙的定义多变量函数。接触过函数式编程的人可能已经知道了。对于一个多变量函数

    ,如果给定参数
    ,就可以得到函数
    。我们知道这个函数的类型是
    。换句话说,输入一个元素
    ,这个二元函数给出了一个一元函数,类型是
    ;这就意味着
    。这个转化称作
    柯里化。我们会频繁地用到这个技巧,因此我们把
    记作右结合的,也就是说
    ,这样可以节省不少括号。

    请读者思考一下

    与之有什么不同,并且给出满足
    的一个元素
    。欢迎在评论区作答。

    三 简单类型的

    -演算与蕴涵逻辑

    先讲讲

    -演算。

    如果我们定义函数的方法纯粹使用上文中的

    -抽象的话,我们的编程语言就会变得非常简单。事实上,我们可以仅用
    -抽象与代入,就构建起一个图灵完备的编程语言;那实际上就是我们要介绍的ITT理论(这个名字以后再解释吧)的骨架。不过,ITT理论通过丰富的类型,以及一些比较好的计算上的性质,更好地发展了
    -演算。在后面讲Church编码的时候,会更详细地提到。

    而仅仅有函数类型的类型论(称作简单类型),对应的逻辑就是蕴涵逻辑。所谓“蕴涵”,指的就是“能推出”的关系。事实上,给一些公理(譬如,题图中的那些),就可以在蕴涵逻辑的基础上完全地描述命题逻辑,也就是不涉及比命题更精细的结构。所谓的“逻辑三段论”等等就是命题逻辑的一部分。

    如果有时间我再多讲讲吧。

    References

    [1] The Univalent Foundations Program,Homotopy Type Theory: Univalent Foundations of Mathematics.

    [2] Wikipedia, Name Resolution (programming languages), Alpha renaming to make name resolution trivial.

    返回目录:zhuanlan.zhihu.com
    a66bb7b726b167e915944668f6c41c0a.png
    展开全文
  • 函数的返回值

    2017-03-10 22:54:47
    函数的返回值用于初始化调用...如果返回类型不是引用,调用函数的地方会将函数的返回值复制给临时对象。当函数返回非引用类型时,其返回值可以是局部对象,也可以是求解表达式的结果。  当返回引用类型时,没有赋
  • C++语言的函数返回值类型分为两类: 内部类型 自定义数据类型 左值:可以放到赋值运算符的左边,能对表达式取地址... 而在函数返回自定义类型(即返回类类型)中根据是否可作为左值,返回值是否可调用成员函数的不..
  • Kotlin 函数都是头等,这意味着它们可以存储变量数据结构中、作为参数传递给其他高阶函数以及从其他高阶函数返回。可以像操作任何其他非函数值一样操作函数。 为促成这点,作为一门静态类型编程语言 Kotlin ...
  • //返回函数的结果,除开void函数,其他返回值类型函数都必须返回一个值,并且return的返回值类型必须函数返回值类型相同,或者能够隐式的转换为相同的类型 void swap(int& a, int& b) { if (a == b) { ...
  • 参数注解:定义函数的时候,参数列表内部的参数后面加上冒号和要传入的类型 def accumlate(x:int, y:int): return x*y 12 返回值注解:参数列表后面,冒号前面,增加一个 -> 符号,后面写返回值的类型。 ...
  • 函数 定义 创建函数用def语句,其格式为:def fun_name(par1,par2,…...需要注意的是,return 语句同一函数中可以出现多次,但只要有一个得到执行,就会直接结束函数的执行。 不带表达式的return相当于返回None。 .
  • 1、怎么给函数编写⽂档? def run(a,b): ''' 参数:a:整数 b:整数 返回值:a+b ...参数注解就是定义函数时,参数列表内部的参数后面加上冒号和要传入的类型,写了参数注解也无法强制限定变量的类
  • 定义函数:Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,缩进块中编写函数体,函数的返回值用return语句返回。 例: 定义函数时,需要确定函数名和参数个数; 如果...
  • 举例说明:在函数对应形参后面冒号说明类型,在def括号后面箭头说明返回值类型。 def func(x: int, y: int) -> int: 3.闭包中,怎么对数字、字符串、元组等不可变元素更新。 使用 nonlocal 关键字。 4.分别根据...
  • 参数注解就是定义函数时,参数列表内部的参数后面加上冒号和要传入的类型,写了参数注解也无法强制限定变量的类型,只能作为提示,来告知使用者应该传入什么类型的参数。如: def accumlate(x:i
  • python中,使用def可以定义一个...就可以定义一个名为hello的函数,其中,return后面的就是该函数的返回值。python的变量类型不固定,所以python的返回值也不固定。 函数从前到后执行,遇到return就会停止,如...
  • 可以在函数中利用双引号“ ”编写文档,利用__doc__、__name__等关键字获取函数的注释、名称等。利用help(MyFirstFunction)指令可以获得函数相关文档。 怎么给函数参数和返回值注解? 函数注解:参数列表内部的...
  • 在函数的首部省略了函数返回值的类型名,则说明该函数的返回值是int类型。 如果函数没有返回值,则必须定义为void类型。 不论函数体中有多少个return语句,只能执行一次。 如果函数体内没有return语句,这时必须...
  • 函数的返回值用于初始化调用函数处创建的临时对象。求解表达式时,如果需要一个地方储存其运算结果,编译器会创建一个没有命名的对象,这就是临时对象。英语中,C++程序员通常用temporary这个术语来代替...
  • 函数 定义函数: def function(形参): 函数体 定义空函数用pass语句 ...调用函数:调用内置或者定义函数,参数个数和参数类型正确。...函数变量作用域:定义在函数内部变量拥有一个局部作用域,定义在函...
  • C++:函数返回值与临时变量

    千次阅读 2019-05-05 20:28:13
    C++规定当函数返回是非引用类型时,函数会创建临时对象(temporary object),函数返回就是这个临时对象。求解表达式时,如果需要一个地方存储其运算结果,编译器会创建一个没有命名对象,这就是临时对象。...
  • 返回值时最简单的方式,它的操作主要在栈上,变量a在函数结束后会删除,为了返回a的值,系统会在内部建立一个临时变量保存a的值,以返回给调用该函数的表达式,调用结束后变量便不再存在。如果a是简单地数据类型也...
  • 总结:返回非引用类型函数的返回值用于初始化调用函数时创建的临时对象(temporary object),如果返回类型不是引用,调用函数的地方会将函数返回值复制给临时对象。 求解表达式的时候,如果需要一个地方存储...
  • Lambda表达式的基本写法: (参数)->表达式或{语句} ,即它是一个匿名函数参数和函数体之间用“->”来表示。 常见写法: (int x) -> {return x+1} //单个参数 (int x) -> x+1 //返回值直接用表达式 (x) ->...
  • 指定函数返回值类型 函数体{ } 特别注意:lambda函数返回的函数句柄 lambda函数实现一元谓词 Lambda函数实现二元谓词 transform函数中使用Lambda函数 Lambda表达式 lambda表达式的基本构造 Lambda...
  • Kotlin 函数都是头等,这意味着它们可以存储变量数据结构中、作为参数传递给其他高阶函数以及从其他高阶函数返回。可以像操作任何其他非函数值一样操作函数。 为促成这点,作为一门静态类型编程语言 Kotlin ...
  • lambda体中调用方法参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值是一致。b.(3)对形参有要求,形参1和形参2lambda表达式中形参1调用某函数,某函数形参是形参2。2.构造器引用调用构造器...
  • C++形式参数和实际参数主调函数和被调函数之间是有数据传递关系的,在调用函数时,函数是带参数的,...在定义函数时,需要在函数首部指定形参的类型。实参形参的类型应相同或赋值兼容。在调用函数时,编译系统会...
  • 前言:最近看技术博文,关于if..else过多情况,以前解决方案一般是用策略模式,但是这篇博文给了个新思路,利用Java 8 Lambda 表达式加上Map与函数式接口来实现优美解决思路。那么问题来了,什么是Lambda ...
  • Lambda 表达式是一种匿名函数,简单地说,它是没有声明方法,也即没有访问修饰符、返回值声明和名字。 你可以将其想做一种速记,你需要使用某个方法地方写上它。当某个方法只使用一次,而且定义很简短,使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 819
精华内容 327
关键字:

在函数的类型与返回值表达式