函数

函数

定义和调用函数

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

定义了一个名为sayHello,形参为String类型的常量personName,返回值类型为String.
函数的形参默认为常量,如果需要为变量,可以在personName前加上var。

无返回值的函数

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

多返回值的函数
使用一个元组类型作为函数的返回类型,来返回一个由多个值组成的复合返回值。

下面的例子定义了一个名为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) 
} 

外部形参名
可以向oc中一样为形参起一个外部名字。

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

第一个形参的外部名称string,本地名称s1;第二个形参的外部名称toString,本地名称s2;第三个形参的外部名称是withJoiner,本地名称为joiner。

可以使用这些外部形参名称清楚明确地调用该函数:

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

你可以写一次名字,并用一个hash符号(#)作为名称的前缀。这就告诉Swift使用名称相同的本地行参名称和外部形参名称。

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" 

默认形参值
指定joiner的默认值为“ ”

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

这样在调用该函数的时候可以不用传递joiner的值,当不传递该值时,joiner默认为“ ”。

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

若你有默认值得形参,但是未显示的指定外部形参名,其会有一个默认的外部形参名,就是其变量名。
如:没有为任何外部形参提供外部名,但仍然提供了joiner形参的默认值:

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

在这种情况下,Swift为带默认值的形参提供了外部形参名,当调用该函数的时候,外部形参名必须让形参的目的明确无歧义:

join("hello", "world", joiner: "-") 
// returns "hello-world" 

可变形参

一个可变形参可接受零个或多个指定类型的值。当函数被调用时,你可以使用可变形参来指定--形参可以用来传递任意数量的输入值。可通过在形参的类型名后边插入三个点符号(...)来编写可变形参。

传递至可变形参的值在函数主体内是以适当类型的数组存在的。例如,一个可变参数的名称为numbers和类型为Double...在函数体内就作为名为numbers类型为Double[]的常量数组。

下边示例为任何长度的数字列表计算算术平均值:

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 

注意:函数最多可以有一个可变形参,而且它必须出现在参数列表的最后,以避免使用多个形参调用函数引发歧义。如果你的函数有一个或多个带有默认值的形参,并且还有可变形参,请将可变形参放在所有默认形参之后,也就是的列表的最末尾。

In-Out 形参

变量形参只能在函数本身内改变。如果你想让函数改变形参值,并想要在函数调用结束后保持形参值的改变,那你可以把形参定义为in-out形参。

你只能传递一个变量作为in-out形参对应的实参。你不能传递一个常量或者字面量作为实参,因为常量和字面量不能被修改。当你把变量作为实参传递给in out形参时,需要在直接在变量前添加 & 符号,以表明它可以被函数修改。

提示:in-out参数不能有默认值,可变参数的参数也不能被标记为inout。如果您标记参数为inout,它不能同时被标记为var或let。

这里的一个叫做swapTwoInts函数,它有两个称为a和b的in-out整型形参:

func swapTwoInts(inout a: Int, inout b: Int) { 
let temporaryA = a 
a = b 
b = temporaryA 
} 

swapTwoInts函数只是简单地交换a、b的值。该函数通过存储一个名为temporaryA临时常量的值,指定b的值到a,然后分配temporaryA到b执行该交换。

你可以通过两个Int类型的变量调用swapTwoInts函数,从而交换它们的值。需要注意的是当它们被传递给swapTwoInts函数时,someInt和anotherInt名称前要加上前缀符号&:

var someInt = 3 
var anotherInt = 107 
swapTwoInts(&someInt, &anotherInt) 
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)") 
// prints "someInt is now 107, and anotherInt is now 3" 

上面的例子表明,someInt和anotherInt的原始值由swapTwoInts函数进行了修改,即使它们定义在函数外部。

函数类型

func addTwoInts(a: Int, b: Int) -> Int { 
return a + b 
} 

你可以定义一个常量或变量为一个函数类型,并为变量指定一个对应的函数:

var mathFunction: (Int, Int) -> Int = addTwoInts 

可以解读为:"定义一个名为mathFunction变量,该变量的类型为'一个函数,它接受两个Int值,并返回一个Int值。'设置这个新的变量来引用名为addTwoInts函数。"

现在你可以使用mathFunction来调用指定的函数:

println("Result: \(mathFunction(2, 3))") 
// prints "Result: 5" 

作为形参类型的函数类型

func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) { 
println("Result: \(mathFunction(a, b))") 
} 
printMathResult(addTwoInts, 3, 5) 
// prints "Result: 8" 

这个例子中定义了一个名为printMathResult函数,它有三个形参。第一个形参名为mathFunction,类型为(Int, Int)->Int。你可以传递任何同类型的函数作为第一个形参的实参。第二和第三个参数a、b都是int类型。被用来作为数学函数的两个输入值。

作为返回类型的函数类型

定义两个函数:

func stepForward(input: Int) -> Int { 
return input + 1 
} 
func stepBackward(input: Int) -> Int { 
return input - 1 
}

这里有一个chooseStepFunction函数,它的返回类型是"函数类型(Int) -> Int"。chooseStepFunction基于名为backwards的布尔形参返回stepBackward或stepForward函数:

func chooseStepFunction(backwards: Bool) -> (Int) -> Int { 
return backwards ? stepBackward : stepForward 
} 

嵌套函数(内部函数)

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 
} 
var currentValue = -4 
let moveNearerToZero = chooseStepFunction(currentValue > 0) 
// moveNearerToZero now refers to the nested stepForward() function 
while currentValue != 0 { 
println("\(currentValue)... ") 
currentValue = moveNearerToZero(currentValue) 
} 
println("zero!") 
// -4... 
// -3... 
// -2... 
// -1... 
// zero! 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360

推荐阅读更多精彩内容