声明(Declarations)
1.0 翻译:marsprince Lenhoon(微博) 校对:numbbbbb, stanzhai
2.0 翻译+校对:Lenhoon, BridgeQ
2.1 翻译:mmoaay, shanks 校对:shanks
2.2 翻译:星夜暮晨
3.0 翻译:chenmingjia
声明 (declaration) 用以向程序里引入新的名字或者结构。举例来说,可以使用声明来引入函数和方法,变量和常量,或者定义新的具有命名的枚举、结构、类和协议类型。还可以使用声明来扩展一个既有的具有命名的类型的行为,或者在程序里引入在其它地方声明的符号。
在 Swift 中,大多数声明在某种意义上讲也是定义,因为声明往往伴随着实现或初始化。由于协议并不提供实现,大多数协议成员仅仅只是声明而已。为了方便起见,也是因为这些区别在 Swift 中并不是很重要,“声明”这个术语同时包含了声明和定义两种含义。
声明语法
导入声明
声明 → 常量声明
声明 → 变量声明
声明 → 类型别名声明
声明 → 函数声明
声明 → 枚举声明
声明 → 结构体声明
声明 → 类声明
声明 → 协议声明
声明 → 构造器声明
声明 → 析构器声明
声明 → 扩展声明
声明 → 下标声明
声明 → 运算符声明
声明 多条声明可选
访问控制级别。
顶级声明语法
顶级声明 → 多条语句可选
导入类型可选导入路径
导入路径标识符 | 导入路径标识符 . 导入路径
模式构造器 | 模式构造器 , 模式构造器列表
构造器可选
协议属性声明。
可以在子类中重写继承来的变量属性,使用 override
声明修饰符标记属性的声明即可,详情请参阅 重写。
构造器可选willSet-didSet代码块
声明修饰符列表可选var
代码块
getter-setter 代码块 → { getter子句 setter子句可选}
getter-setter 代码块 → { setter子句 getter子句 }
代码块
setter名称可选代码块
getter关键字子句 setter关键字子句可选}
getter-setter 关键字代码块 → { setter关键字子句 getter关键字子句 }
willSet子句 didSet子句可选}
willSet-didSet 代码块 → { didSet子句 willSet子句可选}
setter名称可选代码块
setter名称可选代码块
协议关联类型声明。
类型别名头 类型别名赋值
访问级别修饰符可选typealias 类型别名名称
输入输出参数。
函数可以使用元组类型作为返回类型来返回多个值。
函数定义可以出现在另一个函数声明内。这种函数被称作嵌套函数 (nested function)。更多关于嵌套函数的讨论,请参阅 嵌套函数。
函数签名 函数体可选
声明修饰符列表可选func
参数子句列表 throws可选函数结果可选
函数签名 → 参数子句列表 rethrows 函数结果可选
</a> 函数结果 → -> 特性列表可选类型
函数体 → 代码块
参数子句 参数子句列表可选
参数列表 )
参数 | 参数 , 参数列表
扩展声明 中讨论的一样。
访问级别修饰符 可选原始值风格枚举
多个联合风格枚举成员可选}
联合风格枚举成员 多个联合风格枚举成员可选
声明 | 联合风格枚举用例子句
联合风格枚举用例列表
联合风格枚举用例 | 联合风格枚举用例 , 联合风格枚举用例列表
多个原始值风格枚举成员 }
原始值风格枚举成员 多个原始值风格枚举成员可选
声明 | 原始值风格枚举用例子句
原始值风格枚举用例列表
原始值风格枚举用例 | 原始值风格枚举用例 , 原始值风格枚举用例列表
枚举用例名称 原始值赋值可选
原始值字面量
扩展声明。
结构体主体
结构体名称 → 标识符
结构体主体 → { 多条声明可选}
构造器声明 所讨论的,类可以有指定构造器和便利构造器。类的指定构造器必须初始化类中声明的所有属性,并且必须在调用超类构造器之前。
类可以重写属性、方法、下标以及构造器。重写的属性、方法、下标和指定构造器必须以 override
声明修饰符标记。
为了要求子类去实现超类的构造器,使用 required
声明修饰符标记超类的构造器。子类实现超类构造器时也必须使用 required
声明修饰符。
虽然超类属性和方法声明可以被当前类继承,但是超类声明的指定构造器却不能。即便如此,如果当前类重写了超类的所有指定构造器,它就会继承超类的所有便利构造器。Swift 的类并不继承自一个通用基础类。
有两种方法来创建已声明的类的实例:
-
调用类中声明的构造器,请参阅 构造器。
-
如果没有声明构造器,而且类的所有属性都被赋予了初始值,调用类的默认构造器,请参阅 默认构造器。
类实例属性可以用点语法(.
)来访问,请参阅 访问属性。
类是引用类型。当被赋予常量或变量,或者传递给函数作为参数时,类的实例会被引用,而不是被复制。关于引用类型的更多信息,请参阅 结构体和枚举是值类型。
可以使用扩展声明来扩展类的行为,请参阅 扩展声明。
协议主体
协议成员声明列表可选}
协议属性声明
协议成员声明 → 协议方法声明
协议成员声明 → 协议构造器声明
协议成员声明 → 协议下标声明
协议成员声明 → 协议关联类型声明
协议成员声明 协议成员声明列表可选
变量声明。
getter-setter关键字代码块
函数声明。
函数签名
构造器声明。
参数子句 rethrows
下标声明。
下标头 下标结果 getter-setter关键字代码块
类型别名声明。
参数子句 rethrows可选构造器主体
声明修饰符列表可选init !
构造器主体 → 代码块
析构器声明
析构器声明 (deinitializer declaration) 可以为类声明一个析构器。析构器没有参数,遵循如下格式:
deinit {
语句
}
当没有任何强引用引用着类的对象,对象即将被释放时,析构器会被自动调用。析构器只能在类主体的声明中声明,不能在类的扩展声明中声明,并且每个类最多只能有一个析构器。
子类会继承超类的析构器,并会在子类对象将要被释放时隐式调用。继承链上的所有析构器全部调用完毕后子类对象才会被释放。
析构器不能直接调用。
关于如何在类声明中使用析构器的例子,请参阅 析构过程。
协议下标声明 中所述。
更多关于下标的信息和例子,请参阅 下标。
下标头 下标结果 代码块
下标声明 → 下标头 下标结果 getter-setter代码块
下标声明 → 下标头 下标结果 getter-setter关键字代码块
声明修饰符列表可选subscript 参数子句
优先级组声明
下面的形式声明了一个新的前缀运算符:
prefix operator 运算符名称 {}
出现在运算对象前边的前缀运算符是一元运算符,例如表达式 !a
中的前缀非运算符(!
)。
前缀运算符的声明中不指定优先级,而且前缀运算符是非结合的。
下面的形式声明了一个新的后缀运算符:
postfix operator 运算符名称 {}
紧跟在运算对象后边的后缀运算符是一元运算符,例如表达式 a!
中的后缀强制解包运算符(!
)。
和前缀运算符一样,后缀运算符的声明中不指定优先级,而且后缀运算符是非结合的。
声明了一个新的运算符以后,需要实现一个跟这个运算符同名的函数来实现这个运算符。如果是实现一个前缀或者后缀运算符,也必须使用相符的 prefix
或者 postfix
声明修饰符标记函数声明。如果是实现中缀运算符,则不需要使用 infix
声明修饰符标记函数声明。关于如何实现一个新的运算符的例子,请参阅 自定义运算符。
前缀运算符声明 | 后缀运算符声明 | 中缀运算符声明
中缀运算符属性可选}
优先级组名称
Swift标准库操作符参考。
运算符的结合性表示在没有圆括号分组的情况下,同样优先级的一系列运算符是如何被分组的。你可以指定运算符的结合性通过上下文关键字left
、right
或者none
,如果没有指定结合性,默认是none
关键字。左关联性的运算符是从左至右分组的,例如,相减操作符(-)是左关联性的,所以表达式4 - 5 - 6
被分组为(4 - 5) - 6
,得出结果-7。右关联性的运算符是从右往左分组的,指定为none
结合性的运算符就没有结合性。同样优先级没有结合性的运算符不能相邻出现,例如<
运算符是none
结合性,那表示1 < 2 < 3
就不是一个有效表达式。
优先级组的赋值性表示在包含可选链操作时的运算符优先级。当设为true时,与优先级组对应的运算符在可选链操作中使用和标准库中赋值运算符同样的分组规则,当设为false或者不设置,该优先级组的运算符与不赋值的运算符遵循同样的可选链规则。
优先级组名称{多优先级组属性可选 }
优先级组属性多优先级组属性可选{ }
优先级组关系
优先级组属性 → 优先级组赋值性
优先级组属性 → 优先级组相关性
多优先级组名称
优先级组关系 → lowerThan:多优先级组名称
优先级组名称 | 优先级组名称 | 优先级组名称 访问级别修饰符
声明修饰符 声明修饰符列表可选
访问级别修饰符 → internal | internal ( set )
访问级别修饰符 → private | private ( set )
访问级别修饰符 → public | public ( set )