Swift —— 關鍵字

六叔發表於2018-01-11

整理下 Swift 的一些關鍵字。主要包括(不定時更新):

  • @inline(__always)  & @inline(never)
  • @discardableResult
  • mutating
  • associatedtype
  • Designated & Convenience & Required

@inline(__always)  & @inline(never)

正如 C 語言中,可以是 inline 宣告行內函數,Swift 也可以。只需要給函式表明 @inline(__always) 或者 @inline(never)

@inline(never) func testInlineNever() { }
@inline(__always) func testInlineAlways() {}

@discardableResult

在 Swift 中,使用一些有返回值的函式。如果沒有用引數去承接,那麼會有一些警告。一般,我們會用 let _ = 返回值 來消滅這些警告。或者是 使用 @discardableResult 來表明方法,那麼就不會有警告了。

func undiscardResult() -> Bool { return true }

@discardableResult
func discardResult() -> Bool { return true }

// 此處會有警告⚠。所以沒有標明 discardableResult 的話,可以用 let _ = xxx 來消除警告
let _ = undiscardResult()
// 因為有標明 discardableResult ,所以不會有警告⚠
discardResult()

mutating

struct 和 enum 是值型別。預設情況下,無法在例項方法中進行修改。如果要修改的話,那麼需要加上 mutating 進行修飾。這點的話,Xcode 一般會進行提醒。

struct Foo {
    var name : String
    mutating func change(_ name: String) {
        self.name = name
    }
}

associatedtype

來自官網的描述:

When defining a protocol, it’s sometimes useful to declare one or more associated types as part of the protocol’s definition. An associated type gives a placeholder name to a type that is used as part of the protocol. The actual type to use for that associated type isn’t specified until the protocol is adopted. Associated types are specified with the associatedtype keyword.

當定義一個 protocol 的時候,有時候需要制定一些型別,其實就是泛型,用 associatedtype 可以定一個型別。在沒有使用前,可以用 associatedtype 關聯一些實際的型別。在使用上,當實現該協議的時候,需要使用 typealias 來指定 協議中 associatedtype 所關聯的型別。比如 例子中的 Chinese 協議,使用 associatedtype 關聯了一個 Person 的虛擬型別。當 Human 實現 Chinese 這個協議,需要使用 typealias 把 Cantonese 指定為 Person,然後對應的方法也會隨著變成具體型別。不過使用 associatedtype 後,當繼承協議的時候,Xcode 會有提示,需要使用 typealias 。

struct Human { }

struct Cantonese { }

protocol Chinese {
    associatedtype Person
    
    func canEatAnything(_ person: Person) -> Bool
}

extension Human : Chinese {
    typealias Person = Cantonese
    
    func canEatAnything(_ person: Cantonese) -> Bool {
        return true
    }
}

Designated & Convenience & Required

Swift 的構造方法要求比較嚴格。涉及到的關鍵字主要是 Designated 、 Convenience 、 Required 。

Designated 的意思大概是指定的,顧名思義,其修飾的構造方法是首要的,並且每個類都至少有一個 designated 構造方法,父類的可被子類所繼承。

Convenience 的中文含義是便利的。顧名思義,其修飾的構造方法只是便利而已。因此,在優先順序上,convenience 修飾的構造方法排第二。而且,在使用上,必須在同一個類內,呼叫 designated 修飾的構造方法。父類的無法被子類所繼承。

兩者的關係可以從官方文件的這個關係圖看出。

p1

required 修飾的構造方法則是要求子類必須實現父類的這個構造方法。比如說經常用的自定義 UIView,Xcode 則會提示需要實現對應的 required 方法。

class Human {
    var name : String
    var age : Int
    
    init(_ name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    required init(_ name: String) {
        self.name = name
        self.age = 0
    }
    
    convenience init(_ age: Int) {
        self.init("", age: age)
    }
}

class Chinese : Human {
    // 父類的 designated 構造方法,子類可以進行過載
    override init(_ name: String, age: Int) {
        super.init(name, age: age)
    }
    
    // 父類標明的 required 構造方法,子類必須實現
    required init(_ name: String) {
        fatalError("init has not been implemented")
    }
    
    // 父類標明的 convenience 構造方法,不被子類所繼承
}

參考:官方文件:構造方法

結語

暫時就這些。不定時更新~~。(逃

相關文章