fix 2.20 extensions
This commit is contained in:
@ -94,3 +94,4 @@ let heartsSymbol = BlackjackCard.Suit.Hearts.toRaw()
|
||||
|
||||
对于上面这个例子,这样可以使`Suit`, `Rank`, 和 `Values`的名字尽可能的短,因为它们的名字会自然的由被定义的上下文来限定。
|
||||
|
||||
preview
|
||||
@ -1,5 +1,4 @@
|
||||
> 翻译:lyuka
|
||||
|
||||
> 校对:Hawstein
|
||||
|
||||
#扩展(Extensions)
|
||||
@ -27,7 +26,6 @@ Swift 中的扩展可以:
|
||||
|
||||
|
||||
>注意:
|
||||
>
|
||||
如果你定义了一个扩展向一个已有类型添加新功能,那么这个新功能对该类型的所有已有实例中都是可用的,即使它们是在你的这个扩展的前面定义的。
|
||||
|
||||
<a name="extension_syntax"></a>
|
||||
@ -35,7 +33,7 @@ Swift 中的扩展可以:
|
||||
|
||||
声明一个扩展使用关键字`extension`:
|
||||
|
||||
```
|
||||
```swift
|
||||
extension SomeType {
|
||||
// 加到SomeType的新功能写到这里
|
||||
}
|
||||
@ -43,7 +41,7 @@ extension SomeType {
|
||||
|
||||
一个扩展可以扩展一个已有类型,使其能够适配一个或多个协议(protocol)。当这种情况发生时,协议的名字应该完全按照类或结构体的名字的方式进行书写:
|
||||
|
||||
```
|
||||
```swift
|
||||
extension SomeType: SomeProtocol, AnotherProctocol {
|
||||
// 协议实现写到这里
|
||||
}
|
||||
@ -56,7 +54,7 @@ extension SomeType: SomeProtocol, AnotherProctocol {
|
||||
|
||||
扩展可以向已有类型添加计算型实例属性和计算型类型属性。下面的例子向 Swift 的内建`Double`类型添加了5个计算型实例属性,从而提供与距离单位协作的基本支持。
|
||||
|
||||
```
|
||||
```swift
|
||||
extension Double {
|
||||
var km: Double { return self * 1_000.0 }
|
||||
var m : Double { return self }
|
||||
@ -80,7 +78,7 @@ println("Three feet is \(threeFeet) meters")
|
||||
|
||||
这些属性是只读的计算型属性,所有从简考虑它们不用`get`关键字表示。它们的返回值是`Double`型,而且可以用于所有接受`Double`的数学计算中:
|
||||
|
||||
```
|
||||
```swift
|
||||
let aMarathon = 42.km + 195.m
|
||||
println("A marathon is \(aMarathon) meters long")
|
||||
// 打印输出:"A marathon is 42495.0 meters long"
|
||||
@ -88,7 +86,6 @@ println("A marathon is \(aMarathon) meters long")
|
||||
|
||||
|
||||
>注意:
|
||||
>
|
||||
扩展可以添加新的计算属性,但是不可以添加存储属性,也不可以向已有属性添加属性观测器(property observers)。
|
||||
|
||||
<a name="initializers"></a>
|
||||
@ -99,13 +96,12 @@ println("A marathon is \(aMarathon) meters long")
|
||||
扩展能向类中添加新的便利构造器,但是它们不能向类中添加新的指定构造器或析构函数。指定构造器和析构函数必须总是由原始的类实现来提供。
|
||||
|
||||
> 注意:
|
||||
>
|
||||
如果你使用扩展向一个值类型添加一个构造器,该构造器向所有的存储属性提供默认值,而且没有定义任何定制构造器(custom initializers),那么对于来自你的扩展构造器中的值类型,你可以调用默认构造器(default initializers)和逐一成员构造器(memberwise initializers)。
|
||||
正如在值类型的构造器授权中描述的,如果你已经把构造器写成值类型原始实现的一部分,上述规则不再适用。
|
||||
|
||||
下面的例子定义了一个用于描述几何矩形的定制结构体`Rect`。这个例子同时定义了两个辅助结构体`Size`和`Point`,它们都把`0.0`作为所有属性的默认值:
|
||||
|
||||
```
|
||||
```swift
|
||||
struct Size {
|
||||
var width = 0.0, height = 0.0
|
||||
}
|
||||
@ -120,7 +116,7 @@ struct Rect {
|
||||
|
||||
因为结构体`Rect`提供了其所有属性的默认值,所以正如默认构造器中描述的,它可以自动接受一个默认的构造器和一个成员级构造器。这些构造器可以用于构造新的`Rect`实例:
|
||||
|
||||
```
|
||||
```swift
|
||||
let defaultRect = Rect()
|
||||
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
|
||||
size: Size(width: 5.0, height: 5.0))
|
||||
@ -128,7 +124,7 @@ let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
|
||||
|
||||
你可以提供一个额外的使用特殊中心点和大小的构造器来扩展`Rect`结构体:
|
||||
|
||||
```
|
||||
```swift
|
||||
extension Rect {
|
||||
init(center: Point, size: Size) {
|
||||
let originX = center.x - (size.width / 2)
|
||||
@ -140,7 +136,7 @@ extension Rect {
|
||||
|
||||
这个新的构造器首先根据提供的`center`和`size`值计算一个合适的原点。然后调用该结构体自动的成员构造器`init(origin:size:)`,该构造器将新的原点和大小存到了合适的属性中:
|
||||
|
||||
```
|
||||
```swift
|
||||
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
|
||||
size: Size(width: 3.0, height: 3.0))
|
||||
// centerRect的原点是 (2.5, 2.5),大小是 (3.0, 3.0)
|
||||
@ -148,7 +144,6 @@ let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
|
||||
|
||||
|
||||
>注意:
|
||||
>
|
||||
如果你使用扩展提供了一个新的构造器,你依旧有责任保证构造过程能够让所有实例完全初始化。
|
||||
|
||||
<a name="methods"></a>
|
||||
@ -156,7 +151,7 @@ let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
|
||||
|
||||
扩展可以向已有类型添加新的实例方法和类型方法。下面的例子向`Int`类型添加一个名为`repetitions`的新实例方法:
|
||||
|
||||
```
|
||||
```swift
|
||||
extension Int {
|
||||
func repetitions(task: () -> ()) {
|
||||
for i in 0..self {
|
||||
@ -170,7 +165,7 @@ extension Int {
|
||||
|
||||
定义该扩展之后,你就可以对任意整数调用`repetitions`方法,实现的功能则是多次执行某任务:
|
||||
|
||||
```
|
||||
```swift
|
||||
3.repetitions({
|
||||
println("Hello!")
|
||||
})
|
||||
@ -181,7 +176,7 @@ extension Int {
|
||||
|
||||
可以使用 trailing 闭包使调用更加简洁:
|
||||
|
||||
```
|
||||
```swift
|
||||
3.repetitions{
|
||||
println("Goodbye!")
|
||||
}
|
||||
@ -197,7 +192,7 @@ extension Int {
|
||||
|
||||
下面的例子向Swift的`Int`类型添加了一个新的名为`square`的修改方法,来实现一个原始值的平方计算:
|
||||
|
||||
```
|
||||
```swift
|
||||
extension Int {
|
||||
mutating func square() {
|
||||
self = self * self
|
||||
@ -218,7 +213,7 @@ someInt.square()
|
||||
|
||||
...等等
|
||||
|
||||
```
|
||||
```swift
|
||||
extension Int {
|
||||
subscript(digitIndex: Int) -> Int {
|
||||
var decimalBase = 1
|
||||
@ -240,7 +235,7 @@ extension Int {
|
||||
|
||||
如果该`Int`值没有足够的位数,即下标越界,那么上述实现的下标会返回0,因为它会在数字左边自动补0:
|
||||
|
||||
```
|
||||
```swift
|
||||
746381295[9]
|
||||
//returns 0, 即等同于:
|
||||
0746381295[9]
|
||||
@ -251,7 +246,7 @@ extension Int {
|
||||
|
||||
扩展可以向已有的类、结构体和枚举添加新的嵌套类型:
|
||||
|
||||
```
|
||||
```swift
|
||||
extension Character {
|
||||
enum Kind {
|
||||
case Vowel, Consonant, Other
|
||||
@ -276,7 +271,7 @@ extension Character {
|
||||
|
||||
现在,这个嵌套枚举可以和一个`Character`值联合使用了:
|
||||
|
||||
```
|
||||
```swift
|
||||
func printLetterKinds(word: String) {
|
||||
println("'\\(word)' is made up of the following kinds of letters:")
|
||||
for character in word {
|
||||
@ -299,5 +294,5 @@ printLetterKinds("Hello")
|
||||
函数`printLetterKinds`的输入是一个`String`值并对其字符进行迭代。在每次迭代过程中,考虑当前字符的`kind`计算属性,并打印出合适的类别描述。所以`printLetterKinds`就可以用来打印一个完整单词中所有字母的类型,正如上述单词`"hello"`所展示的。
|
||||
|
||||
>注意:
|
||||
>
|
||||
由于已知`character.kind`是`Character.Kind`型,所以`Character.Kind`中的所有成员值都可以使用`switch`语句里的形式简写,比如使用 `.Vowel`代替`Character.Kind.Vowel`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user