注意: 没有定义返回类型的函数会返回特殊的值,叫 Void。它其实是一个空的元组(tuple),没有任何元素,可以写成()。
使用元组作为返回参数,返回多个参数
func count(string: String) -> (vowels: Int, consonants: Int, others: Int) { var vowels = 0, consonants = 0, others = 0 for character in string { 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) }
外部参数名..是为了调用该函数时让其参数更为有表现力,更为通顺,同时还保持了函数体是可读的和有明确意图的。让别人阅读整段代码时更方便
当其他人在第一次读你的代码,函数参数的意图显得不明显时,考虑使用外部参数名。如果函数参数名的意图是很明显的,那就不需要定义外部参数名了
func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String { return s1 + joiner + s2 } join(string: "hello", toString: "world", withJoiner: ", ")
如果你需要提供外部参数名,但是局部参数名已经定义好了,那么你不需要写两次参数名。相反,只写一次参数名,并用井号(#)作为前缀就可以了。这告诉 Swift 使用这个参数名作为局部和外部参数名。
func containsCharacter(#string: String, #characterToFind: Character) -> Bool { for character in string { if character == characterToFind { return true } } return false }
将带有默认值的参数放在函数参数列表的最后。这样可以保证在函数调用时,非默认参数的顺序是一致的,同时使得相同的函数在不同情况下调用时显得更为清晰。
当你未给带默认值的参数提供外部参数名时,Swift 会自动提供外部名字。此时外部参数名与局部名字是一样的,就像你已经在局部参数名前写了井号(#)一样。
func join(s1: String, s2: String, joiner: String = " ") -> String { return s1 + joiner + s2 } join("hello", "world", joiner: "-") // returns "hello-world"
一个可变参数(variadic parameter)可以接受一个或多个值.传入可变参数的值在函数体内当做这个类型的一个数组。
func arithmeticMean(numbers: Double...) -> Double { var total: Double = 0 for number in numbers { total += number } return total / Double(numbers.count) }
函数参数默认是常量。试图在函数体中更改参数值将会导致编译错误。这意味着你不能错误地更改参数值
注意: 对变量参数所进行的修改在函数调用结束后便消失了,并且对于函数体外是不可见的。变量参数仅仅存在于函数调用的生命周期中。
func alignRight(var string: String, count: Int, pad: Character) -> String { let amountToPad = count - countElements(string) for _ in 1...amountToPad { string = pad + string } return string } //下面这样会报错 func test(a:String){ a = "sssss"; }
func swapTwoInts(inout a: Int, inout b: Int) { let temporaryA = a a = b b = temporaryA } var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt);// "someInt is now 107, and anotherInt is now 3”
函数类型,可以让一个变量可以成为多个函数,同时可以把函数当参数进行传递或者当做返回值
var mathFunction: (Int, Int) -> Int = addTwoInts func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) { println("Result: \(mathFunction(a, b))") } func chooseStepFunction(backwards: Bool) -> (Int) -> Int { func stepForward(input: Int) -> Int { return input + 1 } func stepBackward(input: Int) -> Int { return input - 1 } return backwards ? stepBackward : stepForward }
闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。Swift 会为您管理在捕获过程中涉及到的所有内存操作。
闭包表达式:
{ (parameters) -> returnType in statements }
闭包作为函数参数的话,由于类型推断...可以省去闭包参数的类型和返回值闭
reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } ) reversed = sorted(names, { s1, s2 in return s1 > s2 } )
包函数体内如果是单一表达式,还可以省去return语句
reversed = sorted(names, { s1, s2 in s1 > s2 } )
reversed = sorted(names, { $0 > $1 } ) reversed = sorted(names, >)
如果您需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性。 尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
let digitNames = [ 0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine" ] let numbers = [16, 58, 510] let strings = numbers.map { (var number) -> String in var output = "" while number > 0 { output = digitNames[number % 10]! + output number /= 10 } return output }
闭包可以在其定义的上下文中捕获常量或变量。
即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
闭包是引用类型。但是注意,当一个嵌套函数内的函数作为返回值的时候实际上是创建了一个新的函数.
//全局函数 var str = "Hello, playground" func test(a:String=""){ println(str) } test(); //"Hello, playground" str = "Hello"; test(); //"Hello" //嵌套函数 func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount //runningTotal return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) incrementByTen() // 返回的值为10 incrementByTen() // 返回的值为20 incrementByTen() // 返回的值为30 //由于是创建了一个新函数..所以会像下面显示 let incrementBySeven = makeIncrementor(forIncrement: 7) incrementBySeven() // 返回的值为7 incrementByTen() // 返回的值为40 //由于是引用类型.所以 let alsoIncrementByTen = incrementByTen alsoIncrementByTen() // 返回的值为50
注意: Swift 会决定捕获引用还是拷贝值。 您不需要标注amount或者runningTotal来声明在嵌入的incrementor函数中的使用方式。 Swift 同时也处理runingTotal变量的内存管理操作,如果不再被incrementor函数使用,则会被清除。
原文地址:http://www.cnblogs.com/zhepama/p/3857290.html