函数
函数定义
- 定义函数使用关键字 func,可以指定一个或多个输入参数和一个返回值类型。
- 函数的实参传递的顺序必须与形参列表相同,-> 后定义函数的返回值类型。
func funcname(形参) -> returntype
{
Statement1
Statement2
……
Statement N
return parameters
}
元组作为函数返回值
函数返回值类型可以是字符串,整型,浮点型等。
- 元组与数组类似,不同的是,元组中的元素可以是任意类型,使用的是圆括号。
- 可以用元组(tuple)类型让多个值作为一个复合值从函数中返回。
- 如果不确定返回的元组一定不为nil,那么你可以返回一个可选的元组类型,在元组类型的右括号后放置一个问号来定义一个可选元组。
注意:可选元组类型如(Int, Int)?与元组包含可选类型如(Int?, Int?)是不同的.可选的元组类型,整个元组是可选的,而不只是元组中的每个元素值。
函数参数名称
-
函数参数都有一个外部参数名和一个局部参数名。
-
局部参数名: 局部参数名在函数的实现内部使用。
-
外部参数名:可以在局部参数名前指定外部参数名,中间以空格分隔,外部参数名用于在函数调用时传递给函数的参数。
注意:如果你提供了外部参数名,那么函数在被调用时,必须使用外部参数名。
参数类型
- 可变参数: 可以接受零个或多个值。函数调用时,你可以用可变参数来指定函数参数,其数量是不确定的。在变量类型名后面加入(…)的方式来定义。
- 默认在函数中定义的参数都是常量参数,只可以查询使用,不能改变它的值。如果想要声明一个变量参数,可以在参数定义前加 inout 关键字。
- 当传入的参数作为输入输出参数时,需要在参数名前加 & 符,表示这个值可以被函数修改。
函数类型
- 在 Swift 中,使用函数类型就像使用其他类型一样。例如,可以定义一个类型为函数的常量或变量,并将适当的函数赋值给它
func sum(a: Int, b: Int) -> Int {
return a + b
}
var addition: (Int, Int) -> Int = sum
print("输出结果: \(addition(40, 89))")
- 函数类型可以作为参数类型、函数类型作为返回类型
函数嵌套
- 函数嵌套指的是函数内定义一个新的函数,外部的函数可以调用函数内定义的函数。
闭包
闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。 与匿名函数比较相似。全局函数和嵌套函数其实就是特殊的闭包。
- 闭包的形式有:
全局函数 | 嵌套函数 | 闭包表达式 |
---|---|---|
有名字但不能捕获任何值。 | 有名字,也能捕获封闭函数内的值。 | 无名闭包,使用轻量级语法,可以根据上下文环境捕获值。 |
- 语法:以下定义了一个接收参数并返回指定类型的闭包语法:
{(parameters) -> return type in
statements
}
- 以下闭包形式接收两个参数并返回布尔值:
{(Int, Int) -> Bool in
Statement1
Statement 2
---
Statement n
}
闭包表达式
sorted 方法:Swift 标准库提供了名为 sorted(by:) 的方法,会根据您提供的用于排序的闭包函数将已知类型数组中的值进行排序。
- 排序完成后,sorted(by:) 方法会返回一个与原数组大小相同,包含同类型元素且元素已正确排序的新数组。
- 原数组不会被 sorted(by:) 方法修改。sorted(by:)方法需要传入两个参数
- 已知类型的数组
- 闭包函数,该闭包函数需要传入与数组元素类型相同的两个值,并返回一个布尔类型值来表明当排序结束后传入的第一个参数排在第二个参数前面还是后面。如果第一个参数值出现在第二个参数值前面,排序闭包函数需要返回 true,反之返回 false。
参数名称缩写
-
Swift 自动为内联函数提供了参数名称缩写功能,可以直接通过$0,$1,$2来顺序调用闭包的参数
-
如果在闭包表达式中使用参数名称缩写, 可以在闭包参数列表中省略对其定义, 并且对应参数名称缩写的类型会通过函数类型进行推断。in 关键字同样也可以被省略
尾随闭包
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。
func someFunctionThatTakesAClosure(closure: () -> Void) {
// 函数体部分
}
// 以下是不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure({
// 闭包主体部分
})
// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
// 闭包主体部分
}
注意: 如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,您甚至可以把()省略掉。
捕获值
- 闭包可以在其定义的上下文中捕获常量或变量。
- 即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
- Swift最简单的闭包形式是嵌套函数,也就是定义在其他函数的函数体内的函数。嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量。
闭包是引用类型
- 无论将函数/闭包赋值给一个常量还是变量,实际上都是将常量/变量的值设置为对应函数/闭包的引用。
- 如果将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包
枚举
枚举简单的说也是一种数据类型,只不过是这种数据类型只包含自定义的特定数据,它是一组有共同特性的数据的集合。
枚举的功能为:
- 它声明在类中,可以通过实例化类来访问它的值。
- 枚举也可以定义构造函数(initializers)来提供一个初始成员值;可以在原始的实现基础上扩展它们的功能。
- 可以遵守协议(protocols)来提供标准的功能。
语法:
使用 enum 关键词来创建枚举并且把它们的整个定义放在一对大括号内:
enum enumname {
// 枚举定义放在这里
}
注意: 和 C 和 Objective-C 不同,Swift 的枚举成员在被创建时不会被赋予一个默认的整型值。这些枚举成员本身就有完备的值。
-
当枚举的类型已知时,再次为其赋值可以省略枚举名。使用显式类型的枚举值可以让代码具有更好的可读性。
-
相关值与原始值的区别
相关值 | 原始值 |
---|---|
不同数据类型 | 相同数据类型 |
实例: enum {10,0.8,“Hello”} | 实例: enum {10,35,50} |
值的创建基于常量或变量 | 预先填充的值 |
相关值是当你在创建一个基于枚举成员的新常量或变量时才会被设置,并且每次当你这么做得时候,它的值可以是不同的。 | 原始值始终是相同的 |
- 原始值可以是字符串,字符,或者任何整型值或浮点型值。每个原始值在它的枚举声明中必须是唯一的。
- 在原始值为整数的枚举时,不需要显式的为每一个成员赋值,Swift会自动为你赋值。
结构体
可以为结构体定义属性(常量、变量)和添加方法,从而扩展结构体的功能。
与 C 和 Objective C 不同的是:
- 结构体不需要包含实现文件和接口。
- 结构体允许我们创建一个单一文件,且系统会自动生成面向其它代码的外部接口。
- 结构体总是通过被复制的方式在代码中传递,因此它的值是不可修改的。
语法:
通过关键字 struct 来定义结构体:
struct nameStruct {
Definition 1
Definition 2
……
Definition N
}
可以使用结构体来定义你的自定义数据类型。
- 结构体实例总是通过值传递来定义你的自定义数据类型。
- 按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:
- 结构体的主要目的是用来封装少量相关简单数据值。
- 有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。
- 任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。
- 结构体不需要去继承另一个已存在类型的属性或者行为。