swift语言期末关联值(Xcode 6.3 Beta发布,Swift 1.2带来哪些新变化)

本文目录
- Xcode 6.3 Beta发布,Swift 1.2带来哪些新变化
- Swift-细说枚举(Enum)
- #8 swift 枚举类型
- swift 枚举(枚举关联值、枚举原始值、递归枚举等)
- Swift 枚举(enum)详解
Xcode 6.3 Beta发布,Swift 1.2带来哪些新变化
从Xcode 6.3 Beta Release Notes看出,Xcode 6.3 Beta包含了很多颇为值得开发者期待的改变,共计50多处改动,同时修改了Objective-C的语法,足见苹果对Swift语言的重视。而其代码迁移工具可以帮助开发者将其代码从Swift 1.1(Xcode 6.1)升级至Swift 1.2(Xcode 6.3),具体执行菜单(Edit)-》转换(Convert)-至(To)Swift1.2即可。 具体更新如下:
Swift语言的增强
Swift现在支持目标增量编译,例如当一个文件改变时不会重新编译Target中的每一个文件。这个基于固有依赖分析。所以你依然会看到有很多文件在必要情况下被重编。如果你发现需要重编但没有重编的情况,请报一个Bug出来。清理Target后再编,会按照往常的流程进行。
增加了一个新的Set数据类型,它提供了元素唯一化,且有完整语义的通用数据类型集合。它和NSSet类型桥接,提供和Array和Dictionary相类似的功能。
if let语句现在被扩展为可以支持多条条件判断:
view plaincopy
if let a = foo(), b = bar() where a 《 b,
let c = baz() {
}
它允许你测试多种选择,并且包含一个bool判断。当然这种情况不包含嵌套判断。
let常量现在生成时不需要立即初始化,新的规则是let常量必须在被首次使用前初始化即可(和var一样)。或者说它只能被初始化,也就是说在初始化后它不能再被改变或者重新赋值,可用的模式如下:
view plaincopy
let x: SomeThing
if condition {
x = foo()
} else {
x = bar()
}
use(x)
这个正常的来说需要var变量用法,尽管这里没有任何修改的操作。
"Static"静态方法和属性现在允许在class中使用(作为“class final”的别名)。你现在可以在类中声明一个静态存储属性,它享有全局存储空间和首次使用再初始化的惰性构造功能。协议Protocal现在会声明一个static的类型要求而不是声明一个class的要求。
对于表达式闭包的类型引用有了几点改进:
含有单返回语句的闭包现在类型检查时以单表达式闭包处理。
匿名的且含有非空返回类型的单表达式现在可以用在Void上下文中。
多表达式的闭包类型的情况可能无法被类型推断出来,这归功于缺乏返回类型的情况能被正确的推断出来。
Swift中的枚举类型现在可以通过@objc关键字导出到Objective-C中。@objc的枚举类型必须定义一个整型的原始类型,并且该枚举不能泛型化或者不能使用关联值。由于Objective-C中的枚举类型没有命名空间,所以导出到Objective-C中的枚举类型以枚举名字和case项目名字的组合的方式使用。 比如在Swift中的声明:
view plaincopy
@objc
enum Bear: Int {
case Black, Grizzly, Polar
}《br》
导出到Objective-C:
view plaincopy
typedef NS_ENUM(NSInteger, Bear) {
BearBlack, BearGrizzly, BearPolar
};
Objective-C语言的扩展语法现在可以判断出Objective-C API中指针或者block的是否为空,同时允许不带ImplicitlyUnwrappedOptional协议地导出Objective-C API函数。
Swift现在可以部分支持导入C的联合类型,包括unions、bitfileds、SIMD vector类型以及其他Swift的不支持的C特性。这些不被支持的元素不能在Swift中的直接访问,但是在Swift中,Objective-C或者C可以以参数或者返回类型的方式使用。这包括Foundation NSDecimal类型、GLKit GLKVector和GLKMatrix类型,以及其他一些类型。
被导入的C结构体现在在Swift中有一个默认的构造器,它会将结构体中的所有的元素初始化为0,例如:
view plaincopy
import Darwin
var devNullStat = stat()
stat("/dev/null", &devNullStat)
如果一个结构体的元素不能被正确的初始化为0(比如被标记为新的_nonnull标示符时),这个默认的构造器将会终止。
String的索引类型间新的转换API现在可以用了,如String、String.UnicodeScalarView、String.UTF16View以及String.UTF8View, 同时每个String View转换为String的函数也可使用。
类型值在println函数或者字符串内插算法中现在可以打印完整的类型名称了:
view plaincopy
toString(Int.self) // 打印 “Swift.Int"
println(.self) // 打印 "Swift.Array《Swift.Float》”
println((Int, String).self) // 打印 "(Swift.Int, Swift.String)"
一个新的“@noescape”属性可以用在函数的闭包参数上,这意味着这个参数是唯一可被调用的(或者用在函数调用时以参数的方式出现),其意思是它的生命周期比函数调用的周期短,这有助于一些小小的性能优化,但最重要的是它屏蔽了闭包中对self.的需求。这使得函数的控制流比其他更加透明。在未来的beta版本中,标准库函数将普遍采用这种特性,比如autoreleasepool():
view plaincopy
func autoreleasepool(@noescape code: () -》 ()) {
pushAutoreleasePool()
code()
popAutoreleasePool()
}
相比Swift 1.1,Swift 1.2在很多方面的性能上有本质的提高,比如多维数组算法更快,未优化的代码更加快速。
表达式类型的错误诊断有了很大的提高。
很多通用表达式的检查效率有很大提高,这个有助于降低编译时间和减少“expression too complex”的错误。
Swift-细说枚举(Enum)
声明一个方向的枚举,包含四个枚举值: 东/西/南/北.
Swift 的枚举成员在被创建时本身就是完备的值,这些值的类型是已经明确定义好的 Direction 类型. 不会像 Objective-C 一样被赋予一个默认的整型值。在上面的 Direction 例子中,east、west 、north、south不会被隐式地赋值为 0,1,2 和 3。
Swift 中的枚举更加灵活,不必给每一个枚举成员提供一个值。如果给枚举成员提供一个值(称为原始值),则该值的类型可以是:字符串、字符、任意的整数值或浮点类型。
Swift的枚举类型提供了一个叫原始值(RawValues)的实现,它为枚举项提供了一个默认值,这个默认值在编译期间就是确定的。
通过原值值获取的枚举项是可选类型的,所以需要用if let 做一下判断。
未指定枚举值类型
隐式原始值
隐式原始值下枚举项使用系统的分配值:
显式原始值
隐式 + 显式原始值
这里使用了属性观察者,Swift里面的枚举更像一个对象,因此可以很方便的使用属性观察者对枚举值进行监听。
在 Swift 中,还可以定义这样的枚举类型,它的每一个枚举项都有一个附加信息,来扩充这个枚举项的信息表示,这又叫做关联值。
一定要学会使用关联值,这一点很重要。具体的使用后面的第九节会细说
通常情况下枚举是很容易进行相等判断的。一旦为枚举增加了关联值,Swift就没法正确的比较了,需要自己对该枚举实现 == 运算符。
借助 Comparable 协议,来实现枚举的比较。
遵守 CaseIterable 协议的swift枚举是可以遍历的,通过allCases获取所有的枚举成员.
app里面的接口地址,如果都放一起,命名或者寻找都不方便,可以用枚举的嵌套来设计。可以分散在多个文件中,方便维护和管理。
用枚举来管理系统里面的常量是一个不错的选择。
枚举中不能使用存储属性,但是可以使用计算属性,计算属性的内容是在枚举值或者枚举关联值中得到的。
在这里,可以认为枚举是一个类,introduced是一个成员方法,AppleDeivce.iPhone 就是一个AppleDeivce的实例,case们是它的属性。introduced里面的switch self,其实就是遍历这个匿名属性的所有场景,如iPad,iPhone等,然后根据不同的场景返回不同的值。
可以做枚举的自定义构造方法。
系统的打印协议
让枚举遵守这个协议
枚举可以进行扩展。可以将枚举中的case与method/protocol分隔开,阅读者可以快速消化枚举的内容。
设计一个网络类下的错误信息的处理功能。
在项目中经常使用 UserDefaults 来存储一下简单的用户信息。但是对 Key 的维护不会很方便。而且会想不起来。用枚举+结构体就能很好的解决这个问题。
这么设计APP的存储模块,是不是更有层级感,更加方便使用呢?
递归枚举是拥有另一个枚举作为枚举成员关联值的枚举。当编译器操作递归枚举时必须插入间接寻址层。可以在声明枚举成员之前使用 indirect关键字来明确它是递归的。 也可以声明在整个枚举前,让所有的枚举成员都是递归的。
#8 swift 枚举类型
swift中的枚举( Enumerations )真的是太灵活了,感觉自己已经驾驭不了这匹野马了:loudly_crying_face:。
swift中的枚举特点:
使用 enum 关键词定义枚举类型,这个和其它语言一致 例如
typescript中定义枚举:
swift中: 使用 case 关键词来定义一个新的枚举成员
使用:
可以使用switch匹配单个枚举值
作用:
示例:一种商品有2种编码方式进行追踪:
有时候我们可能需要将枚举中所有的case情况组成一个集合,可以让枚举类型扩展 CaseIterable 协议。
另外swift通过 allCases 属性暴露了枚举类型中所有case 的集合:
注意 Xcode 10.0+ 版本才支持这个属性
作为关联值的替代选择,枚举成员可以被默认值(也称为 原始值 )预填充, 这些原始值的类型必须相同
原始值的理解: 即定义枚举的时候,把枚举的类型也定义了,比如 enum Color: String , 定义其类型为 String 类型
和关联值的区别:
示例:使用ASCII码作为原始值的枚举
当原始值类型为整型或者字符串类型时,不需要显式的给每个枚举成员设置原始值,swift会自动的为你赋值
使用 rawValue 属性可以访问枚举成员的原始值:
对 字符串类型 : 隐式的为该枚举成员的名称
如果枚举类型使用了原始值, 自动获取一个初始化方法 (呵呵,什么鬼),这个方法接收一个 rawValue 的参数,参数类型即为原始值类型,返回值则是枚举成员或 nil
另外, 原始值构造器是一个可失败构造器(failable initializer)
例如,调用构造器创建一个新的枚举实例
特点:
要操作具有递归性质的数据结构,使用递归函数事一种直接的方式:
感觉这个这么复杂,估计用到的地方也比较少,了解即可
因为枚举类型是值类型,赋值一般都是通过拷贝的方式,所以原来的值不会改变,swift中提供了 mutating 关键词用来改变值类型的值
其结构大致如下
swift 枚举(枚举关联值、枚举原始值、递归枚举等)
注意: Swift枚举在创建时未分配默认整数值。spring,summer,autumn和winter不等于隐式0,1,2和3。相反,这些值的类型是已经明确定义好的Season类型
在判断一个枚举类型的值时,switch语句必须穷举所有情况,忽略一个将无法通过编译
枚举遵循CaseIterable 协议
声明存储不同类型关联值的枚举成员(这个定义不提供任何Int或String类型的关联值)
一个成员值是(Int,Int,Int)类型关联值的num
一个成员值是(String,String)类型关联值的str
创建了一个名为code的变量,并为Code.num和Code.str赋值
使用switch语句检查不同类型
注意: 原始值和关联值是不同的。原始值是在定义枚举时被预先填充的值。对于一个特定的枚举成员,它的原始值始终不变。关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化。
枚举之前写indirect来让整个枚举成员在需要时可以递归
Swift 枚举(enum)详解
Swift基础语法总结,来自 苹果官方文档 :
枚举在Swift中是 first-class types。与C,Objective-C中的枚举相比,Swift中枚举功能更强大。它支持很多只有类才有的特性,如: Properties , Methods , Initialization , Extensions , Protocols .
举例:
通常将单个枚举值与switch语句匹配:
当需要迭代枚举中的所有情况时,需要自定义的枚举遵守 CaseIterable 协议
我们可以定义Swift枚举来存储任何给定类型的关联值,而且每种枚举情况的值类型可以不同。
可以将关联值提取为switch语句的一部分。将每个关联值提取为常量(let)或变量(var),以便在switch中处理:
如果枚举case的所有关联值都被提取为常量,或者都被提取为变量,则可以将var或let放置在case名称前面,来提取所有的关联值:
“ 关联值 ”表明了枚举如何存储不同类型的关联值。作为关联值的替代,枚举情况可以预先设置默认值(称 原始值 ),它们都是相同的类型。
原始值可以是字符串,字符,整数或浮点数类型。每个原始值在其枚举声明中必须是唯一的。
当使用存储整数或字符串原始值的枚举时,不必为每种case显式分配原始值,Swift将自动为其分配值。如果使用整数为原始值,则每个case的原始值依次自增1。若第一个case没有设置原始值,则默认为0:
当使用字符串作为原始值时,每个case的隐含值是该case的名称。
使用枚举的 rawValue 属性来访问其原始值:
如果使用原始值类型定义枚举,则枚举会自动接收一个带有原始值的初始化器,并返回可选类型的枚举实例。
递归枚举是将枚举的另一个实例作为一个或多个枚举case的关联值。在枚举case 前面添加关键字 indirect 来指明该枚举case是递归的,这就告诉了编译器插入必要的间接层。
例如,下面是存储简单算术表达式的枚举:
还可以在枚举 enum 之前添加 indirect ,以便为所有具有关联值的枚举case启用间接:
递归函数是处理具有递归结构的数据的简单方法。例如,这是一个计算算术表达式的函数:
Swift 4.2 基础专题详解

更多文章:
decorate是什么意思(decorate是什么意思中文翻译)
2026年2月15日 15:15
编程python电脑配置(如何在win7下安装Python及配置)
2025年10月11日 19:30
原生activemq使用(如何使用activemq 管理页面)
2025年6月27日 15:45
connection常用属性(在delphi7中,ADOconnection与ADOQuery都是用来干什么的,有什么联系或者区别吗)
2026年3月25日 08:45
split hairs(don’t split hairs 翻译一下,要直译和引申义)
2026年8月23日 00:45
profitable什么意思(be beneficial for和be profitable for的区别)
2026年1月18日 11:45
switch可以连接笔记本吗(请问switch怎么投屏到笔记本上玩 switch投屏笔记本的操作方法 详细的教程,谢谢!)
2026年8月28日 18:45














