Swift基础_swift函数方法定义

分享到:

函数

函数都是独立的代码块,各自执行特定的任务。你赋予一个函数可以标识其功能的名称,并且需要时,这个名字用于“调用”这个函数来执行其任务。 Swift的统一函数语法足够灵活,能表达没有参数名称的简单的C型函数的任何东西,本地和外部复杂Objective-C-style方法参数名称为每个参数。一旦函数完成其执行,参数可以提供默认值来简化函数调用,并且可以作为输入输出参数来传递,修改一个传递变量。

Swift中的每个函数都有各自的类型,包括函数的参数类型和返回类型。此类型类似于Swift中的任何其他类型,您可以使用此类型,使它很容易将函数作为参数传递给其他函数,并从函数返回函数。函数也可以写在其他函数中,来封装一个嵌套函数范围内的有用的功能。

定义和调用函数

当你定义一个函数时,您可以选择性地定义一个或多个命名类型值,函数作为输入(称为参数),和/或一个类型的值,当它完成后函数将作为输出返回(称为其返回类型)。

每一个函数都有一个函数名,用于描述该函数所执行的任务。使用一个函数,你用它的名字“调用”函数并将其传递给匹配函数参数类型的输入值(称为参数)。所提供的函数的参数必须与函数的参数列表顺序相同。

以下示例中的函数称为greetingForPerson,因为这就是它的任务——它需要输入一个人的名字,并返回那个人问候语。为了实现这一点,您定义一个输入参数——一个称为personName的字符串值——和字符串的返回类型,它将包含那个人的问候语:

 
func sayHello(personName: String) -> String {
let greeting = "Hello, " + personName + "!"
return greeting
}
 

所有这些信息都包括到函数的定义中,是func关键词的前置式。您用返回箭头- >(连字符后跟一个右尖括号)指示函数返回类型,紧随其后的是返回类型名称。

该定义描述了函数的作用、它期望接受的对象以及该函数被实施后返回结果。在其他代码中,该定义可以清楚明白的调用函数。

 
println(sayHello("Anna"))
// prints "Hello, Anna!"
println(sayHello("Brian"))
// prints "Hello, Brian!"
 
您可以通过将它放在括号内,如sayHelo(“Anna”)的String参数值调用sayHelo函数。如上所说,因为该函数返回一个字符串值,sayHelo 可以包裹在println函数的调用中,去打印该字符串,并返回其值。
 
SayHelo函数的首先定义一个名为greeting的新字符串常数,将其设置成一个简单的问候消息personName。然后,使用return关键字,将这个问候语传回到函数以外。只要问候被调用,函数执行完毕并返回问候语的当前值。
 
你可以通过输入不同的值,多次调用sayHelo函数。上面的例子显示了输入值分别为“Anna”和“Brain”时的结果。该函数在不同情况下都会返回一个对应的问候语句。
 
为了简化这个函数的主体部分,将信息创建和return语句合并到一行中:
<java>
func sayHelloAgain(personName: String) -> String {
return "Hello again, " + personName + "!"
}
println(sayHelloAgain("Anna"))
// prints "Hello again, Anna!"
 

函数参数和返回值

在Swift中,函数参数和返回值是非常灵活的。您可以定义任何东西,从未具名参数的简单效用函数,到具有表达参数名称和不同的参数选项的复杂函数。

多个输入参数

函数可以有多个输入参数,这些可以在函数后的括号内表示,并用逗号分开。

此函数需要一个开始和一个半开区间终点指数,并计算出该范围包含了多少个元素:

 
func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"
 

无参数函数

不要求函数对输入参数进行定义。这是一个没有输入参数的函数,当被调用时,它总是返回相同的字符串消息。

 
func sayHelloWorld() -> String {
return "hello, world"
}
println(sayHelloWorld())
// prints "hello, world"
 

虽然该函数不采取任何参数,但是该函数名依然需要放在括弧中。当函数被调用时,函数名后要有一对空括号。

无返回值的函数

不要求函数对返回类型进行定义。这里有一个版本的sayHelo函数,称为waveGoodbye,它会打印自己的字符串值,而不是返回它:

 
func sayGoodbye(personName: String) {
println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"
 

因为它并不需要返回一个值,该函数的定义不包括返回箭头( - >)或返回类型。

注:严格地说,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
 

第一个函数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)
 

你可以使用这个计数函数计算任意字符串的字符,并检索统计总数为三名为int值的元组:

 
let total = count("some arbitrary string!")
println("\(total.vowels) vowels and \(total.consonants) consonants")
// prints "6 vowels and 13 consonants"
 

注元组的成员不需要在元组从函数中返回时就被命名,因为他们的名字已经被指定为函数的返回类型的一部分。

 

函数参数名

上述所有的函数都定义了其参数的参数名:

 
func someFunction(parameterName: Int) {
// function body goes here, and can use parameterName
// to refer to the argument value for that parameter
}
 

然而,这些参数名称只能在函数本身中使用,而不能在调用函数时使用。这些类型的参数名称被称为当地的参数名称,因为它们只在函数内部使用。

外部参数名称

有时候,去调用一个函数时,去命名函数每个参数是有用的,来表示每个传递给函数的每个引用的目的

如果当你的函数被调用时,你希望你的函数的使用者提供参数名称,除了函数本身的本地参数外,请准确命名每个函数的外部参数,你在它所支持的本地参数名称之前写一个外部参数名称,之间用一个空格来分隔):

 
func someFunction(externalParameterName localParameterName: Int) {
// function body goes here, and can use localParameterName
// to refer to the argument value for that parameter
}
 

注:如果您为参数提供一个外部参数名称,外部名字必须在调用函数时使用。

例如下面的函数;在两个函数间插入第三个字符串“joiner”,以此来连接两个字符串

 
func join(s1: String, s2: String, joiner: String) -> String {
return s1 + joiner + s2
}
 

当你调用这个函数,你传递给函数的这三个字符串的目的是不清楚的

 
join("hello", "world", ", ")
// returns "hello, world"
 

为了使这些字符串的目的更清晰,为每个连接函数参数提供外部参数名称。

 
func join(string s1: String, toString s2: String, withJoiner joiner: String)
-> String {
return s1 + joiner + s2
}
 

这个版本的函数,第一个参数有一个外部名称的字符串和s1的本地名称,第二个参数有一个外部名称toString和s2的本地名称,第三个参数有一个外部的名字withJoiner和当地joiner的名字。

现在,您可以明确的、毫不含糊的使用这些外部参数名称调用该函数

 
join(string: "hello", toString: "world", withJoiner: ", ")
// returns "hello, world"
 

使用外部参数名称使连接函数的第二个版本更具表达力,用户习惯使用类似句子的方式,同时也提供了一个可读的、明确的函数体。

注:对于第一次阅读函数代码而不清楚函数目的时,请考虑使用外部函数名称。当函数被调用时,如果每个函数的目的是清楚的,毫不含糊的,你就不需要指定外部函数名称。

外部参数名称

如果你想为某个函数指定外部参数名称,而参数本身的名字可以恰当的表达其本身,你就不需要重复为这个参数命名。相反,参数名写一次,并用一个hash符号(#)给该函数名加上前缀。这就是Swift将一个名字作为内部参数名称和外部参数名称的方法。

这个例子中定义了一个名为containsCharacter函数,它通过将一个hash符号,在当地的参数名称前定义了函数的两个参数的外部名称:

 
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")
// containsAVee equals true, because "aardvark" contains a "v"
 

默认参数值

可以为任何参数定义一个默认值,作为函数定义的一部分。如果定义了一个默认值,那么在调用一个函数时,该参数可以省略。

注:将使用默认值的参数放在函数的参数列表的末尾。这确保了对该函数的所有调用使用相同的非默认参数顺序,并明确在每种情况下都调用相同的函数。

这里有一个从早期版本的连接函数,它为其jointer参数提供了一个默认值:

 
func join(string s1: String, toString s2: String,
withJoiner joiner: String = " ") -> String {
return s1 + joiner + s2
}
 

如果在连接函数被调用时。字符串会起到连接字符的功能,像以前一样,用于连接两个字符。

 
join(string: "hello", toString: "world", withJoiner: "-")
// returns "hello-world"
 

但是,如果当函数被调用时没有提供jointer上午值,单个空格(“”)将会作为一个默认值来代替:

 
join(string: "hello", toString: "world")
// returns "hello world"
 

含有默认值的参数的外部名称

大多数情况下,提供(如果需要)具有缺省值的任何参数一个外部名称是有用的当函数调用提供的值时,这将确保函数的目的是明确的.

为了使这个过程更容易,如果您不能提供外部名称,Swift自动为你提供缺省参数下的外部名称,自动外部名称与本地名称相同,就像您再在您的本地代码名称前写了一个hash字符。

这是一个早期功能连接的版本,它不提供任何外部名称,但是仍要提供了jointer参数的默认值。

 
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}
 

在这种情况下,Swift 将自动提供一个连接默认值作为外部函数名当调用函数时,外部名字将会被应用,进而使函数可以清楚明确的表达。 </java> join("hello", "world", joiner: "-") // returns "hello-world" </java>

注:当你定义一个函数时,您可以选择用下划线来替代明确的外部名字,然而,缺省值的外部名称在适当的地方总是首选。

可变参数

一个可变参数可以接受零值或指定类型的多个值。当函数被调用时,您可以指定一个可变参数用于传递不同数量的输入值。通过插入省略号来写可变参数的类型名称。

就函数本身,可以通过可变参数值作为适当类型的数组。例如,一个数字的名称和类型…可变的参数在函数体作为常量数组称为型。

下面的例子计算任何长度的列表的算数平均(也成为平均)值

 
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8, 19)
returns 10.0, which is the arithmetic mean of these three numbers
 

注:一个函数可以有至多一个varadic参数,它必须出现在参数列表的最后,避免当调用该函数的参数时产生异议。 如果您的函数有一个或多个参数有默认值,也有一个可变参数,请将这多个参数值放在默认参数的后面。

常量和变量参数

功能参数默认情况下均是常数。编译阶段的错误将试图去改变函数本身的函数参数。这意味着你无法错误地改变参数的值。

然而,对于一个函数

昵    称:
验证码:

相关文档:

swift
IOS实例
ObjectiveC