这是我参与更文挑战的第7天,活动详情查看: 更文挑战
函数定义与调用
在swift中,函数定义使用关键字func
,使用返回箭头->
指向函数返回类型
//函数定义
func sayHI(name:String, age:Int) -> String {
return "我是\(name),今年\(age)岁"
}
//函数调用
let str = sayHI(name: "lily", age: 12)
复制代码
函数参数和返回值(无参数无返回、有参数无返回值、无参数有返回值、有参数有返回值)
- 无参数,无返回值(没有定义返回类型的函数会返回
Void
,它其实是一个空的元组,可以写成()
)func sayHI(){ print("sayHI") } sayHI() log: sayHI 复制代码
- 有参数,无返回值
func sayHI(name:String) { print("hello " + name) } sayHI(name: "李雷") log: hello 李雷 复制代码
- 无参数,有返回值
func sayHI() -> String { return "sayHI" } let str = sayHI() log: sayH 复制代码
- 有参数,有返回值
func sayHI(name:String, age:Int) -> String { return "我是\(name),今年\(age)岁" } let str = sayHI(name: "李雷", age: 12) log: 我是李雷,今年12岁 复制代码
函数参数标签和参数名称
-
指定参数标签
swift支持函数参数标签,这种模式被称为外部形参。如果参数指定了外部形参标签,那么调用的时候就必须显示的使用,参数名称前面编写形参标签,用空格分隔
func sayHI(name nameStr:String, age ageValue:Int) -> String { return "我是\(nameStr),今年\(ageValue)岁" } sayHI(name: "李雷", age: 12) 复制代码
-
省略参数标签
函数不需要参数的参数标签,那么用下划线(
_
)代替参数的参数标签func sayHI(_ nameStr:String, _ ageValue:Int) { print("我是\(nameStr),今年\(ageValue)岁") } sayHI("李雷", 12) 复制代码
-
省略参数标签与下划线(
_
)如果觉得每个参数都指定参数标签或用下划线(
_
)代替参数的参数标签比较繁琐,我们可以直接使用参数名称来代替参数的参数标签func sayHI(nameStr:String, ageValue:Int) { print("我是\(nameStr),今年\(ageValue)岁") } sayHI(nameStr: "李雷", ageValue: 12) 复制代码
-
默认参数值
函数体中可以为参数设置默认值,当默认值被设置之后,调用函数时可以忽略这个参数。一般将设置默认参数的参数放在参数列表的末尾,将没有设置默认值的参数放在函数参数列表的前面
func sayHI(name:String, age:Int = 12) { print("我是\(name),今年\(age)岁") } sayHI(name:"李雷") //我是李雷,今年12岁 sayHI(name:"李雷", age: 18) //我是李雷,今年18岁 复制代码
-
可变参数
- 一个可变参数可以接受零个或多个值
- 函数调用时,函数参数可以传入多个
- 在参数类型名称后面使用(
...
)来定义可变参数 - 可变参数的传入值在函数体中以数组形式读取
- 一个函数最多只能拥有一个可变参数
func message(_ strs:String...) { var totalStr = "" for str in strs { totalStr += str } print(totalStr) } message("s","a","y","H","I") //sayHI 复制代码
-
输入输出参数(
in-out
)默认情况下,函数参数是常量。不能直接在函数内部改变参数的值,也就是说函数的参数默认是值类型的。在实际使用中,往往需要直接在函数内修改参数值,也就是说需要传递的是引用,而不是值,这时我们把这个参数定义为
in-out
。-
in-out
参数可以改变函数体外的值 -
定义
in-out
参数时,在参数定义前加in-out
关键字 -
只能将变量作为
in-out`参数的参数值进行传递,不能传递常量或文字值作为参数,因为不能修改常量和文字 -
当传入的参数作为
in-out
参数时,需要在参数名前加&
,表示这个值可以被函数修改func exchangeValue(valueA:inout Int, valueB:inout Int){ let value = valueA valueA = valueB valueB = value } var a = 3 var b = 5 exchangeValue(valueA: &a, valueB: &b) print("a = \(a), b = \(b)") log: a = 5, b = 3 复制代码
-
函数类型
-
函数类型
每个函数都有一个特定的函数类型,由函数的参数类型和返回类型组成
func add(_ a:Int, _ b:Int) -> Int { return a + b } 复制代码
这个函数的类型是:
(Int, Int) -> Int
,
可以理解为“这个函数类型有俩个Int
型的参数并返回一个Int
型的值”func sayHI(){ print("sayHI") } 复制代码
这个函数的类型是:
() -> ()
,
可以理解为“这个函数类型没有参数,没有返回值,没有返回值的函数通常会返回void
,相当于返回一个空元组” -
函数类型的使用
定义一个类型为函数的常量或变量,并将适当的函数赋值给它
func add(_ a:Int, _ b:Int) -> Int { return a + b } var function :(Int,Int)-> Int = add print(function(2,3)) 复制代码
定义一个叫做 function 的变量,类型是“一个有两个 Int 型的参数并返回一个 Int 型的值的函数”,并让这个新变量指向 add 函数
-
函数类型作为参数
定义了
showResult(_:_:_:)
函数,它有三个参数:第一个参数叫fun
,类型是(Int, Int) -> Int
,你可以传入任何这种类型的函数;第二个和第三个参数分别是a
和b
,它们的类型都是Int
,这两个值作为已给出的函数的输入值func showResult(_ fun:(Int,Int)->Int,_ a:Int,_ b:Int) { print(fun(a,b)) } func add(_ a:Int, _ b:Int) -> Int { return a + b } showResult(add(_:_:), 3, 2) 复制代码
showResult(_:_:_:)
函数的作用就是输出另一个适当类型的数学函数的调用结果。它不关心传入函数是如何实现的,只关心传入的函数是不是一个正确的类型。这使得showResult(_:_:_:)
能以一种类型安全(type-safe)的方式将一部分功能转给调用者实现。 -
函数类型作为返回值
定义了两个简单函数,分别是
sayHI(_:)
和sayHello(_:)
,这两个函数的类型都是(String) -> String
。之后在定义一个showResult(:)
的函数,它的返回类型是(String) -> String
类型的函数。showResult(backward:)
根据布尔值来返回(String) -> String
类型函数func sayHI(_ name:String) -> String { return "HI \(name)" } func sayHello(_ name:String) -> String { return "Hello \(name)" } func showResult(_ backward: Bool) -> (String) -> String { return backward ? sayHI : sayHello } let show = showResult(true) print(show("world")) log: HI world 复制代码
-
嵌套函数
嵌套函数:把函数定义在别的函数中
func showResult(_ backward: Bool) -> (String) -> String {
func sayHI(_ name:String) -> String {
return "HI \(name)"
}
func sayHello(_ name:String) -> String {
return "Hello \(name)"
}
return backward ? sayHI : sayHello
}
let show = showResult(true)
print(show("world")) //HI world
复制代码