[swift 進階]讀書筆記-第六章:函式 C6P5 計算屬性和下標

liaoWorking在掘金發表於2019-01-22

第六章:函式(function)

6.5 計算屬性和下標(computed property and subscript)

知識點1: 什麼是計算屬性

我們直接看下面這個demo ///返回我的名字 /// 複雜度: O(1) var myName:String { return "liaoworking" }

沒有指定setter方法,只讀屬性,myName的值不會被快取,每次被呼叫的時候都會計算一遍。上面這個就是計算屬性 注:swift API指南推薦我們對所有複雜度不是O(1)的計算屬性都應該在文件中寫明(如demo中所示)。因為會假設呼叫計算屬性的耗時是常數時間。

知識點2:宣告一個外部只讀,內部可讀寫的屬性
private(set) var userName:String = ""
複製程式碼

延遲儲存屬性(懶載入 lazy)


相信大家經歷過多年的OC懶載入的洗禮。對lazy的理解深入骨髓! 這裡就只說筆者覺得可以拿來一說的幾點

常規寫法1:
lazy var myAge:Int = { ()-> String in
 return 18
}()

常規寫法2:
///getMyAge() 是一個返回Int型別的方法
lazy var myAge:Int = getMyAge()

常規寫法3
///currentYear 和 birthYear是兩個變數
lazy var myAge:Int = currentYear - birthYear
複製程式碼

使用不同引數過載下標


下標的常規使用

let fibs = [0, 1, 1, 2, 3, 5]
let first = fibs[0]
fibs[1..<3] //[1, 1]
複製程式碼

因為demo的使用場景有限,就是想重寫一個只有起點(從起點到最後)的下標表示。 這裡只說說核心思想步驟。 具體程式碼可見最後附。

我們可以過載下標來定義一個可以使用半有界區間為引數的collection的下標方法來實現

fibs[2..<]
複製程式碼

步驟:

  • 1.定義一個簡單的操作符運算來建立有界區間。 這個涉及到操作符合 ..< 操作符的定義的知識點。

  • 2.給 collection 新增一個extension 把這兩個subscript的方法寫入即可。

下標的進階


下標其實也可以像函式一樣接受多個引數實現原理: 寫一個extension的subscript的方法即可。 Demo主要是以字典的形式展示每個字母出現個個數,Demo具體使用場景太少。瞭解步驟及知識點即可

附:

///過載下標 達到獲取collection半有界區的目的
struct RangeStart<l>{let start : l}
struct RangeEnd<l>{let end : l}

postfix operator ..<
postfix func ..<<l>(lhs: l) -> RangeStart<l> {
    return RangeStart(start: lhs)
}

prefix operator ..+
prefix func ..+<l>(rhs: l) -> RangeEnd<l> {
    return RangeEnd(end: rhs)
}

extension Collection {
    subscript(r: RangeStart<Index>) -> SubSequence {
        return suffix(from: r.start)
    }
    subscript(r: RangeEnd<Index>) -> SubSequence {
        return prefix(upTo: r.end)
    }
}
fibs[2..<]
fibs[..+3]


///實現多引數下標的核心方法
extension Dictionary {
    subscript(key: Key, or defaultValue: Value) -> Value {
        get {
            return self[key] ?? defaultValue
        }
        set {
           self[key] = newValue
        }
    }
}

extension Sequence where Iterator.Element: Hashable {
    var frequencies: [Iterator.Element: Int] {
        var result: [Iterator.Element: Int] = [:]
        for x in self {
            result[x, or: 0] += 1
        }
        return result
    }
}
"hello".frequencies // ["e":1, "0":1, "l":2, "h":1]
複製程式碼

文章原始檔地址

相關文章