函数是执行特定任务的代码自包含块。给定一个函数名称标识, 当执行其任务时就可以用这个标识来进行”调用”。
Swift的统一的功能语法足够灵活来表达任何东西,无论是甚至没有参数名称的简单的C风格的函数表达式,还是需要为每个本地参数和外部参数设置复杂名称的Objective-C语言风格的函数。参数提供默认值,以简化函数调用,并通过设置在输入输出参数,在函数执行完成时修改传递的变量。
Swift中的每个函数都有一个类型,包括函数的参数类型和返回类型。您可以方便的使用此类型像任何其他类型一样,这使得它很容易将函数作为参数传递给其他函数,甚至从函数中返回函数类型。函数也可以写在其他函数中来封装一个嵌套函数用以范围内有用的功能。
1、函数的声明与调用
当你定义一个函数时,你可以为其定义一个或多个不同名称、类型值作为函数的输入(称为参数),当该函数完成时将传回输出定义的类型(称为作为它的返回类型)。
每一个函数都有一个函数名,用来描述了函数执行的任务。要使用一个函数的功能时,你通过使用它的名称进行“调用”,并通过它的输入值(称为参数)来匹配函数的参数类型。一个函数的提供的参数必须始终以相同的顺序来作为函数参数列表。
例如在下面的例子中被调用的函数greetingForPerson,像它描述的那样 — 它需要一个人的名字作为输入并返回一句问候给那个人。
func sayHello(personName: String) -> String {
let greeting = "Hello, " + personName + "!"
return greeting
}
</div>
所有这些信息都汇总到函数的定义中,并以func关键字为前缀。您指定的函数的返回类型是以箭头->(一个连字符后跟一个右尖括号)以及随后类型的名称作为返回的。
该定义描述了函数的作用是什么,它期望接收什么,以及当它完成返回的结果是什么。该定义很容易让该函数可以让你在代码的其他地方以清晰、明确的方式来调用:
println(sayHello("Anna"))
// prints "Hello, Anna!"
println(sayHello("Brian"))
// prints "Hello, Brian!"
</div>
通过括号内String类型参数值调用sayHello的函数,如的sayHello(”Anna”)。由于该函数返回一个字符串值,sayHello的可以被包裹在一个println函数调用中来打印字符串,看看它的返回值,如上图所示。
在sayHello的函数体开始定义了一个新的名为greeting的String常量,并将其设置加上personName个人姓名组成一句简单的问候消息。然后这个问候函数以关键字return来传回。只要问候函数被调用时,函数执行完毕是就会返回问候语的当前值。
你可以通过不同的输入值多次调用sayHello的函数。上面的例子显示了如果它以”Anna”为输入值,以”Brian”为输入值会发生什么。函数的返回在每种情况下都是量身定制的问候。
为了简化这个函数的主体,结合消息创建和return语句用一行来表示:
func sayHello(personName: String) -> String {
return "Hello again, " + personName + "!"
}
println(sayHello("Anna"))
// prints "Hello again, Anna!"
</div>
2、函数的参数和返回值
在swift中函数的参数和返回值是非常具有灵活性的。你可以定义任何东西无论是一个简单的仅仅有一个未命名的参数的函数还是那种具有丰富的参数名称和不同的参数选项的复杂函数。
多输入参数
函数可以有多个输入参数,把他们写到函数的括号内,并用逗号加以分隔。下面这个函数设置了一个开始和结束索引的一个半开区间,用来计算在范围内有多少元素包含:
func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"
</div>
无参函数
函数并没有要求一定要定义的输入参数。下面就一个没有输入参数的函数,任何时候调用时它总是返回相同的字符串消息:
func sayHelloWorld() -> String {
return "hello, world"
}
println(sayHelloWorld())
// prints "hello, world"
</div>
该函数的定义在函数的名称后还需要括号,即使它不带任何参数。当函数被调用时函数名称也要跟着一对空括号。
没有返回值的函数
函数也不需要定义一个返回类型。这里有一个版本的sayHello的函数,称为waveGoodbye,它会输出自己的字符串值而不是函数返回:
func sayGoodbye(personName: String) {
println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"
</div>
因为它并不需要返回一个值,该函数的定义不包括返回箭头( – >)和返回类型。
提示
严格地说,sayGoodbye功能确实还返回一个值,即使没有返回值定义。函数没有定义返回类型但返
回了一个void返回类型的特殊值。它是一个简直是空的元组,实际上零个元素的元组,可以写为()。
当一个函数调用时它的返回值可以忽略不计:
func printAndCount(stringToPrint: String) -> Int {
println(stringToPrint)
return countElements(stringToPrint)
}
func printWithoutCounting(stringToPrint: String) {
printAndCount(stringToPrint)
}
printAndCount("hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting("hello, world")
// prints "hello, world" but does not return a value
</div>
第一个函数printAndCount,打印了一个字符串,然后并以Int类型返回它的字符数。第二个函数printWithoutCounting,调用的第一个函数,但忽略它的返回值。当第二函数被调用时,字符串消息由第一函数打印了回来,去没有使用其返回值。
提示
返回值可以忽略不计,但对一个函数来说,它的返回值即便不使用还是一定会返回的。在函数体底部
返回时与定义的返回类型的函数不能相容时,如果试图这样做将导致一个编译时错误。
多返回值函数
你可以使用一个元组类型作为函数的返回类型返回一个有多个值组成的一个复合作为返回值。
下面的例子定义了一个名为count函数,用它计来算字符串中基于标准的美式英语中设定使用的元音、辅音以及字符的数量:
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)
}
</div>
您可以使用此计数函数来对任意字符串进行字符计数,并检索统计总数的元组三个指定Int值: