返回值
没有定义返回类型的函数,事实上,会返回一个类型为Void
的特殊值。
它是一个空的元组,写为()
。
函数可以以元组的形式返回多个值。
定义返回类型时可以命名元组成员,这样,当元组返回时,可以通过所命名的名字访问。
func minMax(array: [Int]) -> (min: Int, max: Int) {
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
let bounds = minMax([8, -6, 2, 109, 3, 71])
println("min is \(bounds.0) and max is \(bounds.1)")
println("min is \(bounds.min) and max is \(bounds.max)")
如果元组可能是空,可以使用 optional tuple,来说明函数的返回值可能为nil
。
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
if let bounds = minMax([8, -6, 2, 109, 3, 71]) {
println("min is \(bounds.min) and max is \(bounds.max)")
}
(注意(Int, Int)?
和(Int?, Int?)
的区别)
参数名
外部参数名
可以为函数参数提供外部参数名(相较于只能在函数体内部使用的局部参数名)。
之后,调用函数时,就将参数值与外部参数名一一对应。(当定义了外部参数名,调用函数时就必须使用)
func someFunction(externalParameterName localParameterName: Int) {
// function body goes here, and can use localParameterName
// to refer to the argument value for that parameter
}
考虑下面的例子:使用了外部函数名的函数在调用时更具有表达力。
func join(s1: String, s2: String, joiner: String) -> String {
return s1 + joiner + s2
}
join("hello", "world", ", ")
func join(string s1: String, toString s2: String, withJoiner joiner: String)
-> String {
return s1 + joiner + s2
}
join(string: "hello", toString: "world", withJoiner: ", ")
定义外部参数名时,如果想重用局部参数名,可以使用#localParameterName
语法糖。
func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
for character in string {
if character == characterToFind {
return true
}
}
return false
}
let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v")
如果函数参数有默认值,该参数必定有一个外部参数名。
如果没有显示的提供,Swift 会自动提供一个与局部参数名一样的外部参数名。
见如下示例:
func join(string s1: String, toString s2: String,
withJoiner joiner: String = " ") -> String {
return s1 + joiner + s2
}
join(string: "hello", toString: "world", withJoiner: "-")
join(string: "hello", toString: "world")
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}
join("hello", "world", joiner: "-")
join("hello", "world")
当函数中还有变长参数时,变长参数始终出现在参数列表的末尾(变长参数会被收集到一个数组中),
亦即出现在所有有默认值的参数后面,这也是为什么必须有默认值的参数提供外部参数名(不然会产生二义)。
由此也可知道,一个函数最多只能有一个变长参数。
变量参数
函数参数默认都是常量(在函数体中试图改变参数的值会引起编译错误)。
可以在定义函数时给参数添加var
前缀来定义变量参数,这会为函数提供一个可修改的参数值拷贝。
(注意,修改变量参数并不会改变原参数,这是 In-Out 参数的功能)
func alignRight(var string: String, count: Int, pad: Character) -> String {
let amountToPad = count - countElements(string)
if amountToPad < 1 {
return string
}
let padString = String(pad)
for _ in 1...amountToPad {
string = padString + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"
In-Out 参数
函数中对 In-Out 参数的修改可以在函数调用后依旧保持。
函数调用时,传递的参数必须是变量。
In-Out 参数与具有默认值的参数和变长参数不兼容。
func swapTwoInts(inout a: Int, inout b: Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
函数类型
函数可传递,可返回,可嵌套,概念与 Scala 中的函数类似。
特殊说明:无参数无返回类型的函数类型为 () -> ()
。