在 Swift 语言简明教程(七) - 集合类型 中, 我们了解了 Swift 中集合类型的用法,现在我们来了解一下 Swift 中的函数 - Function。
Swift 中函数的语法与C/C+、Java 相比有一些不同,可能是考虑与 Objective-C(OC)的集成,所以在定义和调用时保留了一些OC语言的一些特点,对于习惯了 C/C++、Java 的开发人员来说要一点时间来适应。
函数的定义
在 Swift 中,需要使用关键字 “func” 来定义函数,然后跟上函数名,接着在括号中定义参数,再用 “->” 指明返回值类型,最后跟上函数体。
1 | func 函数名(参数列表)-> 返回值类型 {} |
下面我们按照这个定义来定义一个函数,函数的功能是简单的判断传入的一个数字是否大于10。 定义如下:
1 | func isMoreThanTen(count:Int) -> Bool { |
每个参数定义的形式为:
1 | 参数名: 数据类型 |
多个参数用“,”号分割。
如果没有参数,可以更一个空的括号,如:
1 | func myFunc1()->String{ |
如果不需要返回值,可以用两种方式定义
- 指明返回类型为 Void
1 | func myFunc2() -> Void { |
- 直接忽略 “->“
1 | func myFunc3() { |
调用函数
注意:调用函数时,与 C/C++、Java 的不同点主要在参数列表上
现在,让我们来调用在上节中定义的函数: isMoreThanTen
1 | isMoreThanTen(count: 9) |
注意:在调用时参数名不能省略
1 | isMoreThanTen(20) // 这样调用是不能通过编译的 |
理解参数的内部、外部名
下面我们来看看有多个参数的情况,先定义一个有三个参数的函数如下:
1 | func myFunc5(param1: Int,param2: Int,param3: Int) -> Int { |
这里,我们引入了 swift 中的特有名词:参数的内部命名。 在调用时需要给相应的参数内部名, 如调用 myFunc5,我们需要这样写:
1 | myFunc5(param1: 1, param2: 2, param3: 3) |
注意,虽然你给定每个参数的内部名,但并不代表你可以改变参数列表的顺序,下面这样的调用是不能通过编译的
1 | myFunc5(param3: 1, param2: 2, param1: 3) // 报错 |
我们还可以为函数定义外部参数名,如为上面的 myFunc5 加上外部函数名,如下:
1 | func myFunc5(out1 param1: Int,ou2 param2: Int,ou3 param3: Int) -> Int { |
这里使用的param1,param2,param3是参数的内部命名, out1, out2, out3 是外部参数名。
有外部参数名时,要用外部参数名进行调用,所以调用变成
1 | myFunc5(out1: 1, ou2: 2, ou3: 3) |
用内部参数是不能通过编译的,如:
1 | myFunc5(param1: 1, param2: 2, param3: 3) // 报错 |
当然,也可以显示的忽略外部参数名,这样来定义:
1 | func myFunc5(param1:Int,_ param2:Int , _ param3:Int) -> Int { |
注意:用” _ “号对对外部参数名进行了占位,这样在调用时就可以忽略参数名了。如:
1 | myFunc5(param1: 1, 2, 3) |
参数默认值(缺省值)
在定义函数的参数时,我们也可以为参数指定默认值,在调用时,对于没有给定实际参数的就用参数的默认值。 如:
定义函数 myFunc8,设定默认参数param2的值为10,param3的值为5
1 | func myFunc8(param1:Int,param2:Int = 10 ,param3:Int = 5) -> Int { |
可以这样调用 myFunc8
- 对每个参数都进行传值
1 | myFunc8(param1: 1, param2: 1, param3: 1) |
- 只对没有设置默认值的参数传值
1 | myFunc8(param1: 10) |
- 对部分参数传值
1 | myFunc8(param1: 20, param3: 30) |
注意,有默认值的参数不需要排列在参数列表的末尾
不定长参数
swift 中允许”…”定义不确定个数的参数,如下面的函数中定义个多个顺利不定的整型参数,实际上,这些参数可以通过参数名象列表一样存取。
1 | func myFunc10(param:Int...){ |
调用时,可以给不同数量的参数,如:
1 | myFunc10(param: 1,2,3,4,5) |
和 Java 不同, Java中的变成参数必须时最后一个参数,在 swift 中没有这个限制,如:
1 | func myFunc11(param1:Int...,param2:String) { |
调用方法:
1 | myFunc11(param1: 1,2,3, param2: "hello") |
inout 参数
通常,把参数传入函数后,如果在函数中改变了改参数的值,这个改变后的值也不能够被带出函数体的范围。 那如果需要带出来,要怎么做呢? swift 提供了 inout 类型的参数。
1 | func myFunc12( param:inout Int){ |
在 myFunc12 中,为了能将在函数中改变后的 param 的值带出来(不实用返回值的方式),可以在参数类型前加上 inout。
调用时,需要做一些特殊处理,如调用 myFunc12:
1 | var para = 10; |
注意:在变量名前加了 & 符号, 可以理解为其它语言中的”取地址“操作。
函数类型
在 Swift 中,函数也可以作为一种数据类型,在 C/C++ 中叫函数指针。函数类型的声明的语法就是把函数定义的语法中的函数体去掉,如:
1 | var addFunc:(Int,Int)->Int |
这样,我们就声明了一个包含两个 Int 参数,返回类型也是 Int 的函数变量。对于这个变量,我们可以有几种赋值方式。
- 直接赋值一个已定义的函数, 如:
1 | func myFunc13(param1:Int,param2:Int) -> Int { |
- 通过一个函数来返回
我们构造一个函数来给这个变量赋值。
1 | func myFunc15() -> (Int,Int)->Int { |
当然,我们也可以这样写:
1 | func myFunc16() -> (Int,Int)->Int { |
- 定义一个匿名的函数
直接上代码:
1 | addFunc = { |
在参数中使用函数类型
函数既然可以作为一种数据类型,当然也可以用在参数列表中,如:
定义一个函数,可以传入类型为 (Int,Int)->Int 的函数类型,
1 | func myFunc14(param:(Int,Int)->Int) { |
接下来,就可以把上一节中定义的 addFunc 作为调用 myFunc14 参数:
1 | myFunc14(param: addFunc) |