02-Swift4 中 Private 的 使用範圍

weixin_34234823發表於2018-05-03
struct Date {
    private let secondsSinceReferenceDate: Double
}

extension Date: Equatable {
    static func ==(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate == rhs.secondsSinceReferenceDate
    }
}

extension Date: Comparable {
    static func <(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate < rhs.secondsSinceReferenceDate
    }
}

上面的程式碼在Swift3 中無法執行,因為 會報錯:

  • 因 secondsSinceReferenceDate 是 Private 屬性,所以不可以在 extension 中訪問。
extension Date: Equatable {
    static func ==(lhs: Date, rhs: Date) -> Bool {
        // 1. 在 swift3 不能這麼寫,因為會得到一個錯誤
        // error: 'secondsSinceReferenceDate' is inaccessible due to private protaction level
        // 2.1 secondsSinceReferenceDate 是私有保護,所以無法訪問
        return lhs.secondsSinceReferenceDate == rhs.secondsSinceReferenceDate
    }
}

如果在 swift3中想要 屬性在 extension 中被訪問到,那屬性需要 改成 fileprivate, 但結果就是 在 整個檔案中都可以被檢索到。

struct Date {
    
    // 2.2 private 是私有宣告,所以在 extension 中沒有辦法獲取到 secondsSinceReferenceDate
     // private let secondsSinceReferenceDate: Double
    
    // 2.3 可以使用 Fileprivate 來解決 private 的私有宣告
    // 但意味著此定義 在整個檔案中都可以被檢索到,這樣不好。範圍太廣了
     fileprivate let secondsSinceReferenceDate: Double
}

在 Swift 4 中,從新擴充套件了 私有定義(Private)的範圍,覆蓋同一原始檔中特定型別的所有擴充套件的宣告,這與使用擴充套件來元件的程式碼的概念更加吻合;
所以以後再同一檔案中,可以不使用 fileprivate 使用 private

SE-0169: Improve Interaction Between Private Declarations and Extensions

相關文章