2.Checking API Availability
Swift有内置的API可用性检查,它保证了你不会误用在当前系统上不支持的API,如果你使用了则会在运行时报错,你可以使用#available 配合if 或guard 来实现。
if@H_404_13@
@H_404_13@
#available@H_404_13@
(@H_404_13@
iOS@H_404_13@
@H_404_13@
9@H_404_13@
,@H_404_13@
OSX@H_404_13@
@H_404_13@
10.10@H_404_13@
,*) {
@H_404_13@ // Use iOS 9 APIs on iOS,and use OS X v10.10 APIs on OS X
@H_404_13@ } @H_404_13@ else@H_404_13@ {
@H_404_13@ //Fall back to earlier iOS and OS X APIs@H_404_13@
@H_404_13@ // Use iOS 9 APIs on iOS,and use OS X v10.10 APIs on OS X
@H_404_13@ } @H_404_13@ else@H_404_13@ {
@H_404_13@ //Fall back to earlier iOS and OS X APIs@H_404_13@
}@H_404_13@
中间用逗号隔开,* 表示其它任何平台,写在括号内的表示可执行的系统的最低版本。你不能在可用性条件语句之间加上&& 或者|| 这样的运算符。
3.Early Exit
guard关键字和if 类似,语句的执行都是取决于布尔类型的真假,guard关键字必须要搭配else 一起使用。
如果guard 后的布尔类型为真,就会跳过else 继续执行,在guard 判断时所定义的变量在剩下的代码块中也是可用的;
如果判断为假,就会进入else 语句执行,这个分支必须起到终结代码块的作用,比如可以使用return ,break,throw 或者 continue,你也可以调用一个没返回值的函数,比如fatalError()。
4.Protocol Extension
协议可以被拓展来为那些声明满足协议的类型提供方法和变量。
extension@H_404_13@
@H_404_13@
RandomNumberGenerator@H_404_13@
{
@H_404_13@ func@H_404_13@ randomBool() -> @H_404_13@ Bool@H_404_13@ {
@H_404_13@ return@H_404_13@ random() > @H_404_13@ 0.5@H_404_13@
}@H_404_13@
@H_404_13@ func@H_404_13@ randomBool() -> @H_404_13@ Bool@H_404_13@ {
@H_404_13@ return@H_404_13@ random() > @H_404_13@ 0.5@H_404_13@
}@H_404_13@
}@H_404_13@
let@H_404_13@
generator = LinearCongruentialGenerator() @H_404_13@
//满足RandomNumberGenerator协议
@H_404_13@
print(@H_404_13@ "Here's a random number @H_404_13@ \@H_404_13@ (@H_404_13@ @H_403_222@generator@H_404_13@ .random()@H_404_13@ )"@H_404_13@ )@H_404_13@
@H_404_13@
print(@H_404_13@ "Here's a random number @H_404_13@ \@H_404_13@ (@H_404_13@ @H_403_222@generator@H_404_13@ .random()@H_404_13@ )"@H_404_13@ )@H_404_13@
print("And here's a random Boolean: @H_404_13@@H_404_13@
\@H_404_13@
(@H_404_13@@H_404_13@@H_404_13@
generator@H_404_13@
.randomBool@H_404_13@@H_404_13@)"@H_404_13@@H_404_13@
)@H_404_13@
你可以使用协议拓展来为所有满足协议的类型提供方法或变量的默认实现,如果某类型内部提供了它自己的实现方法,那么协议提供的默认方法就不会被调用,而是采用其内部定义的方法。(译者注:类似于类中子类对父类函数的重载)
你也可以使用where关键字来为协议的拓展增加限制。
CollectionType@H_404_13@
@H_404_13@
where@H_404_13@
Generator.Element : TextRepresentable {
@H_404_13@ func@H_404_13@ asList() -> @H_404_13@ String@H_404_13@ {
@H_404_13@ return@H_404_13@ @H_404_13@ ""@H_404_13@
}@H_404_13@
@H_404_13@ func@H_404_13@ asList() -> @H_404_13@ String@H_404_13@ {
@H_404_13@ return@H_404_13@ @H_404_13@ ""@H_404_13@
}@H_404_13@
}@H_404_13@
5.Where Clauses
protocol@H_404_13@
Container {
@H_404_13@ typealias@H_404_13@ ItemType
@H_404_13@ mutating@H_404_13@ @H_404_13@ func@H_404_13@ append (item: @H_404_13@ ItemType@H_404_13@ )
@H_404_13@ var@H_404_13@ count: @H_404_13@ Int@H_404_13@ { @H_404_13@ get@H_404_13@ }
@H_404_13@ subscript@H_404_13@ (i: @H_404_13@ Int@H_404_13@ ) -> @H_404_13@ ItemType@H_404_13@ { @H_404_13@ get@H_404_13@ }
}
@H_404_13@ func@H_404_13@ allItemMatch<C1: Container,C2: Container @H_404_13@ where@H_404_13@ C1.ItemType == C2.ItemType,C1.ItemType: Equatable> (someContainer: @H_404_13@ C1@H_404_13@ ,162)">_@H_404_13@ anotherContainer: @H_404_13@ C2@H_404_13@ ) -> @H_404_13@ if@H_404_13@ someContainer.@H_404_13@ count@H_404_13@ != anotherContainer.@H_404_13@ count@H_404_13@ {
@H_404_13@ return@H_404_13@ @H_404_13@ false@H_404_13@
}
@H_404_13@ for@H_404_13@ i @H_404_13@ in@H_404_13@ @H_404_13@ 0@H_404_13@ ..<someContainer.@H_404_13@ if@H_404_13@ someContainer[i] != anotherContainer[i] {
@H_404_13@ false@H_404_13@
}
}
@H_404_13@ true@H_404_13@
@H_404_13@ typealias@H_404_13@ ItemType
@H_404_13@ mutating@H_404_13@ @H_404_13@ func@H_404_13@ append (item: @H_404_13@ ItemType@H_404_13@ )
@H_404_13@ var@H_404_13@ count: @H_404_13@ Int@H_404_13@ { @H_404_13@ get@H_404_13@ }
@H_404_13@ subscript@H_404_13@ (i: @H_404_13@ Int@H_404_13@ ) -> @H_404_13@ ItemType@H_404_13@ { @H_404_13@ get@H_404_13@ }
}
@H_404_13@ func@H_404_13@ allItemMatch<C1: Container,C2: Container @H_404_13@ where@H_404_13@ C1.ItemType == C2.ItemType,C1.ItemType: Equatable> (someContainer: @H_404_13@ C1@H_404_13@ ,162)">_@H_404_13@ anotherContainer: @H_404_13@ C2@H_404_13@ ) -> @H_404_13@ if@H_404_13@ someContainer.@H_404_13@ count@H_404_13@ != anotherContainer.@H_404_13@ count@H_404_13@ {
@H_404_13@ return@H_404_13@ @H_404_13@ false@H_404_13@
}
@H_404_13@ for@H_404_13@ i @H_404_13@ in@H_404_13@ @H_404_13@ 0@H_404_13@ ..<someContainer.@H_404_13@ if@H_404_13@ someContainer[i] != anotherContainer[i] {
@H_404_13@ false@H_404_13@
}
}
@H_404_13@ true@H_404_13@
}@H_404_13@
如上述代码,C1与C2是泛型,C1C2的具体类型不必相同,但必须都满足Container协议,而且C1.ItemType需要与C2的ItemType相同,ItemType需要满足Equatable协议。
补充:
该协议可以直接使数组类型满足,通过查看定义可知数组是结构体类型,在数组类型的定义中存在append() 和 subscript满足协议要求,虽然数组的定义中没有ItemType类型,但Swift可通过协议定义配合数组本身的定义推测出ItemType的类型。