• <small id="w8oog"></small>
  • <td id="w8oog"></td>
  • <small id="w8oog"></small><xmp id="w8oog"><td id="w8oog"></td><td id="w8oog"><li id="w8oog"></li></td><xmp id="w8oog"><td id="w8oog"></td>
  • <td id="w8oog"></td><td id="w8oog"><li id="w8oog"></li></td><small id="w8oog"></small>
  • <td id="w8oog"></td>
  • <small id="w8oog"></small>
  • <small id="w8oog"></small><td id="w8oog"></td>
    免費開源的iOS開發學習平臺

    Swift:17 擴展

    擴展就是為一個已有的類、結構體、枚舉類型或者協議類型添加新功能。這包括在沒有權限獲取原始源代碼的情況下擴展類型的能力(即逆向建模)。擴展和Objective-C中的類別類似。(與Objective-C不同的是,Swift的擴展沒有名字。)

    擴展語法

    使用關鍵字extension來聲明擴展:

    extension SomeType{
        // 為 SomeType 添加的新功能寫到這里
    }
    

    可以通過擴展來擴展一個已有類型,使其遵守一個或多個協議。在這種情況下,無論是類還是結構體,協議名字的書寫方式完全一樣:

    extension SomeType: SomeProtocol, AnotherProctocol {
        // 協議實現寫到這里
    }
    

    計算型屬性

    擴展可以為已有類型添加計算型實例屬性和計算型類型屬性。下面的例子為Swift的內建Int類型添加了四個計算型實例屬性,來演示存儲單位Byte、KB、MB和GB之間的換算關系。這些屬性是只讀的計算型屬性,為了更簡潔,省略了get關鍵字。它們的返回值是Int,而且可以用于所有接受Int值的數學計算中:

    extension Int{
        var B: Int { return self  }
        var KB : Int { return self * 1024 }
        var MB: Int { return self * 1024*1024 }
        var GB: Int { return self * 1024*1024*1024 }
    }
    
    let fileSize = 4.KB
    print("1KB = \(fileSize) Byte")
    
    let bigFileSize = 4.GB
    print("1GB = \(bigFileSize) Byte")
    
    let sum = 1024.KB + 3.MB
    
    print("1024B + 3KB = \(sum) Byte")
    

    代碼執行結果如下圖。

    構造器

    擴展可以為已有類型添加新的構造器。這可以讓你擴展某個類型,將你自己的定制類型作為其構造器參數,或者提供該類型的原始實現中未提供的額外初始化選項。擴展能為類添加新的便捷構造器,但是它們不能為類添加新的指定構造器或析構器。指定構造器和析構器必須總是由原始的類實現來提供。下面演示通過擴展的方式為Rect結構體添加便捷構造器的過程。

    struct Size {
        var width = 0.0, height = 0.0
    }
    struct Point {
        var x = 0.0, y = 0.0
    }
    
    struct Rect {
        var origin = Point()
        var size = Size()
        func toString()  {
            print("[origin:(\(origin.x),\(origin.y)),size:(\(size.width),\(size.height))]")
        }
    }
    extension Rect{
        init(center: Point, size: Size) {
            let originX = center.x - (size.width / 2)
            let originY = center.y - (size.height / 2)
            self.init(origin: Point(x: originX, y: originY), size: size)
        }
    }
    
    let r1 = Rect()
    r1.toString()
    
    let r2 = Rect(origin: Point(x:10,y:10), size: Size(width: 6.0, height: 6.0))
    r2.toString()
    
    let r3 = Rect(center: Point(x:13,y:13), size: Size(width: 6.0, height: 6.0))
    r3.toString()
    

    代碼執行結果截圖如下圖所示。

    方法

    擴展可以為已有類型添加新的實例方法和類型方法。下面的例子為Int類型添加了一個名為repetitions的實例方法,通過添加該方法,可以重復執行一段代碼。

    extension Int {
        func repetitions(task: () -> Void) {
            for _ in 0..<self {
                task()
            }
        }
    }
    //調用三次閉包函數
    3.repetitions({
        print("Hello!")
    })
    //Hello!
    //Hello!
    //Hello!
    
    //如果函數最后一個參數是閉包,也可以使用尾隨閉包讓調用更加簡潔
    3.repetitions {
        print("Goodbye!")
    }
    //Goodbye!
    //Goodbye!
    //Goodbye!
    

    可變實例方法

    通過擴展添加的實例方法也可以修改該實例本身。結構體和枚舉類型中修改self或其屬性的方法必須將該實例方法標注為mutating,正如來自原始實現的可變方法一樣。下面代碼演示整型自增。

    extension Int {
        mutating func addOne() {
            self +=  1
        }
    }
    var someInt = 3
    someInt.addOne() 
    //someInt現在的值為4
    

    下標

    擴展可以為已有類型添加新下標。下面這個例子為Swift類型Int添加了一個整型下標。該下標[n]返回十進制數字從右向左數的第n個數字:

    123456789[

    123456789[1] 返回 8

    ……以此類推。

    extension Int {
        subscript(digitIndex: Int) -> Int {
            var decimalBase = 1
            for _ in 0..<digitIndex {
                decimalBase *= 10
            }
            return (self / decimalBase) % 10
        }
    }
    746381295[0]  // 返回 5
    
    746381295[1] // 返回 9
    
    746381295[2] // 返回 2
    
    746381295[8] // 返回 7
    
    746381295[9] // 返回 0
    

    嵌套類型

    擴展可以為已有的類、結構體和枚舉添加新的嵌套類型,下面示例演示了通過擴展Int類型,來判斷Int的值是正數、零還是負數三種情況。

    extension Int {
        enum Kind {
            case Negative, Zero, Positive
        }
        var kind: Kind {
            switch self {
            case 0:
                return .Zero
            case let x where x > 0:
                return .Positive
            default:
                return .Negative
            }
        }
    }
    
    func printIntegerKinds(_ numbers: [Int]) {
        for number in numbers {
            switch number.kind {
            case .Negative:
                print("- ", terminator: "")
            case .Zero:
                print("0 ", terminator: "")
            case .Positive:
                print("+ ", terminator: "")
            }
        }
        print("")
    }
    
    printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
    

    代碼運行結果如下圖所示。

    示例代碼

    https://github.com/99ios/23.18


    ijzzijzzij亚洲大全|天天狠天天透天干天天|日本一本加勒比五月天伊人久久|久久久噜噜噜久久中文字幕色伊伊
  • <small id="w8oog"></small>
  • <td id="w8oog"></td>
  • <small id="w8oog"></small><xmp id="w8oog"><td id="w8oog"></td><td id="w8oog"><li id="w8oog"></li></td><xmp id="w8oog"><td id="w8oog"></td>
  • <td id="w8oog"></td><td id="w8oog"><li id="w8oog"></li></td><small id="w8oog"></small>
  • <td id="w8oog"></td>
  • <small id="w8oog"></small>
  • <small id="w8oog"></small><td id="w8oog"></td>