簡體   English   中英

確定通用(可能是協議)類型的協議一致性

[英]Determine Protocol Conformance of Generic (Possibly Protocol) Type

即使在通用類型本身就是協議本身的情況下,在Swift中也可以檢查通用類型是否符合協議

protocol Parent {}
protocol Child: Parent {}
struct ParentType: Parent {}
struct ChildType: Child {}

func generic<T>(possiblyParent: T?) {
    if T.self is Parent.Type { //Only works for non-protocol types :(
        print("Parameter conforms to Parent.")
    }
}

let one: Parent? = nil
let two: Child? = nil
let three: ParentType? = nil
let four: ChildType? = nil

generic(one) //no, but I wish yes
generic(two) //no, but I wish yes
generic(three) //yes
generic(four) //yes

《 Swift編程指南:類型

協議類型的元類型(不是在運行時符合協議的具體類型)是該協議的名稱,后跟.Protocol 例如,類類型SomeClass的元類型是SomeClass.Type ,協議SomeProtocolSomeProtocol.Protocol

將此應用於您的問題,您可以執行以下操作:

func generic<T>(possiblyParent: T?) {
    guard let p = possiblyParent else { return }

    // You could use an if statement instead of a switch here, if you wanted.
    switch p.dynamicType {
        case is Parent.Type, is Parent.Protocol:
            print("Parameter conforms to Parent.")
        default:
            print("Parameter doesn't conform to Parent")
    }
}

用法:

let one  : Parent = ParentType()
let two  : Child  = ChildType()
let three: Parent = ChildType()

generic(one)     // Prints: Parameter conforms to Parent.
generic(two)     // Prints: Parameter conforms to Parent.
generic(three)   // Prints: Parameter conforms to Parent.
generic("Hello") // Prints: Parameter doesn't conforms to Parent.

您可以嘗試使用標准的可選強制轉換:

func generic<T>(possiblyParent: T?) {
    if let _ = possiblyParent as? Optional<Parent> {
        print("Parameter conforms to Parent.")
    }
}

在Swift 2.0 b3上,當您傳遞的可選參數不是nil時,它似乎可以正常工作。

但不幸的是:

let someInt: Int? = 3  // no and it is correct
let nilInt: Int? = nil // yes, but it should be no

這可能是一個錯誤。 無論如何,如果possiblyParent為零,通常您可以做的更多。

因此,如果您的目的是在不為空的情況下實際使用該參數,則可能更喜歡這樣的通用函數:

func generic<T>(possiblyParent: T?) {
    if let p = possiblyParent, // parameter is not empty
    let parent = p as? Parent  // parameter content conforms to Parent {
        print("parent can be safely used as a Parent.")
    }
}

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM