認(rèn)識(shí)Swift系列10之下標(biāo)(類(lèi)、結(jié)構(gòu)體、枚舉皆可用)

    // 下標(biāo)subscript本質(zhì)就是一個(gè)方法
    // 使用下標(biāo)定義了方法后,外部可以通過(guò)中括號(hào)[]方式方位setter和getter方法
    // subscript方法的返回值類(lèi)型決定了set的newValue類(lèi)型和get方法的返回值類(lèi)型
    class Point {
        var x = 0.0, y = 0.0, z = 0.0
        subscript(index: Int) -> Double {
            set {
                if index == 0 {x = newValue}
                else if index == 1 {y = newValue}
                else  {z = newValue}
            }
            get {
                if index == 0 {return x}
                else if index == 1 {return y}
                else  {return z}
            }
        }
        
        subscript(index: String) -> Double {
            set {
                if index == "x" {x = newValue}
                else if index == "y" {y = newValue}
                else  {z = newValue}
            }
            get {
                if index == "x" {return x}
                else if index == "y" {return y}
                else  {return z}
            }
        }
        
        func show() {
            print("x == \(x),y == \(y),z == \(z)")
        }
    }
    
    let p = Point()
    p.show()
    
    p[0] = 20
    p[1] = 1
    p[2] = 9
    p.show()
    
    p["x"] = 33
    p["y"] = 44
    p["z"] = 55
    p.show()
    
    
    // subscript可以沒(méi)有set方法,但是必須要有g(shù)et方法,只有g(shù)et的時(shí)候,可以省略get
    // 必須有g(shù)et,可以省略set
    class Size {
        var w = 0.0, h = 0.0
        // 只有g(shù)et
        /**
         subscript(index: Int) -> Double {
             get {
                 if index == 0 {return w}
                 else  {return h}
             }
         }
         */
        // 只有g(shù)et可以省略get
        subscript(index: Int) -> Double {
            if index == 0 {return w}
            else  {return h}
        }
        
        func show() {
            print("w == \(w),h == \(h)")
        }
    }
    
    // 可以設(shè)置參數(shù)標(biāo)簽
    class Point1 {
        var x = 0.0, y = 0.0, z = 0.0
        subscript(indexTag index: Int) -> Double {
            set {
                if index == 0 {x = newValue}
                else if index == 1 {y = newValue}
                else  {z = newValue}
            }
            get {
                if index == 0 {return x}
                else if index == 1 {return y}
                else  {return z}
            }
        }
        func show() {
            print("x == \(x),y == \(y),z == \(z)")
        }
    }
    
    let p1 = Point1()
    p1.show()
    
    p1[indexTag: 0] = 23
    p1[indexTag: 1] = 33
    p1[indexTag: 2] = 43
    p1.show()
    
    // 下標(biāo)可以傳多個(gè)參數(shù)
    // 下標(biāo)可以使類(lèi)方法
    class Point2 {
        static subscript(v1: Int, v2: Int) -> Int {
            v1 + v2
        }
    }
    print(Point2[1, 10])
    
    // 下標(biāo)返回結(jié)構(gòu)體和類(lèi)的區(qū)別
    // 當(dāng)結(jié)構(gòu)體類(lèi)添加下標(biāo)方法的時(shí)候,有適合可能必須加入set方法
    func testStruct() {
        class File {
            var x = 0, y = 0
        }
        class FileManager {
            var f = File()
            subscript(index: Int) ->File { f }
        }
        
        let fm = FileManager();
        fm[0].x = 10
        fm[0].y = 10
        print("class fm f (\(fm.f.x), \(fm.f.y))")
    }
    func testClass() {
        struct File {
            var x = 0, y = 0
        }
        struct FileManager {
            var f = File()
            subscript(index: Int) ->File {
                set {
                    f = newValue
                    // 雖然外部值修改f的x屬性,但實(shí)際操作是外部會(huì)構(gòu)建新的結(jié)構(gòu)體來(lái)進(jìn)行值覆蓋
                }
                get {f}
            }
        }
        
        var fm = FileManager();
        fm[0].x = 10 // f = File(x: 10, y: fm[0].y)
        fm[0].y = 10 // f = File(x: fm[0].x, y: 10)
        // 兩句代碼雖然是對(duì)f成員的x和y賦值,但對(duì)于結(jié)構(gòu)體來(lái)說(shuō)實(shí)際上是內(nèi)存中值得copy過(guò)程
        // 即 f.x = 10 等價(jià)于 f = File(x:10 y:f.y)
        // 因此,fm[0].x = 10實(shí)際上需要調(diào)用下標(biāo)方法中的set方法
        // 所以,下標(biāo)方法必須實(shí)現(xiàn)set
        
        print("class fm f (\(fm.f.x), \(fm.f.y))")
    }
    testStruct()
    testClass()
    
    // 接收多個(gè)參數(shù)的下標(biāo)
    class Grid {
        static let NotFound = -1
        var data = [
            [0, 1, 2],
            [3, 4, 5],
            [6, 7, 8]
        ]
        
        subscript(row: Int, column: Int)->Int {
            set {
                guard (row >= 0 && row < 3) && (column >= 0 && column < 3) else { return }
                data[row][column] = newValue
            }
            get{
                guard (row >= 0 && row < 3) && (column >= 0 && column < 3) else { return Grid.NotFound }
                return data[row][column]
            }
        }
    }
    
    var g = Grid()
    g[0, 0] = 40
    g[1, 1] = 40
    g[2, 2] = 40
    print(g.data)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容