2015-09-10 72 views
1

是否有可能返回一種符合協議的泛型,以便以後使用Swift 1.2的類函數使用?看看:返回Generic.Type以備將來與類方法一起使用

protocol SomeProtocol 
{ 
    static func start(kind: Kind) 
} 

class A: SomeProtocol 
{ 
    class func start(kind: Kind) 
    { 
     print("A started") 
    } 
} 

class B: SomeProtocol 
{ 
    class func start(kind: Kind) 
    { 
     print("B started") 
    } 
} 


enum Kind { 
    case Akind 
    case Bkind 

    private func classKind<T: SomeProtocol>() -> T.Type 
    { 
     switch self { 
      case .Akind: return A.self 
      case .Bkind: return B.self 
     } 
    } 

    func doSomething() { 
     self.classKind().start(self) 
    } 
} 

我試過各種方法,但每個方法都以一些錯誤結束。目前,我得到的'A'不是classKind方法中的'T'的子類型(與'B'相同),並且不能用doSomething中的類型'(Kind)'的參數列表調用'start'。 我敢肯定,我很接近,但解決不了......

回答

1

如果您使用斯威夫特2,實現你想要什麼,你只需要改變:

private func classKind<T: SomeProtocol>() -> T.Type { ... } 

private func classKind() -> SomeProtocol.Type { ... } 

現在又回到了不工作的代碼,看看那裏的錯誤是來自何處。您不需要進行我現在詳述的更改,這只是爲了解釋錯誤。

首先檢查你的doSomething方法:

func doSomething() { 
    self.classKind().start(self) 
    // Error: Argument for generic parameter 'T' could not be inferred. 
    // 
    // (I'm using Xcode 7 b6, which may explain the differing error messages) 
} 

對於由classKind返回類型推斷,你必須做的:

let type: A.Type = self.classKind() // Or you could use `B.Type`. 
type.start(self) 

這顯然違背了你的目標點,因爲你必須指定你想要的類型。


其次,錯誤的classKind

private func classKind<T: SomeProtocol>() -> T.Type 
{ 
    switch self { 
    case .Akind: return A.self 
    // Cannot convert return expression of type 'A.Type' to return type 'T.Type'. 

    case .Bkind: return B.self 
    // Cannot convert return expression of type 'B.Type' to return type 'T.Type'. 
    } 
} 

爲了說明爲什麼這不起作用考慮下面的例子中,我有另一種類型符合SomeProtocol

struct C: SomeProtocol { ... } 

然後在doSomething

func doSomething() { 
    let type: C.Type = self.classKind() 
    type.start(self) 
} 

您現在可以讀取的錯誤爲:Cannot convert return expression of type 'A.Type'/'B.Type' to return type 'C.Type'

+0

那麼,沒有辦法實現我想要的?我的主要目標是在'doSomething'方法中使用'type.start(...)',而不需要明確寫入顯式類型。 – Kubba

+0

在我的答案的第一位,我說你需要做什麼才能使它工作:)我編輯我的答案,希望使這一點更清晰。 – ABakerSmith

+0

之後,您在'doSomething()'中更改'classKind() - > SomeProtocol.Type'我得到:訪問協議類型值'SomeProtocol.Type'的成員未實現 – Kubba

相關問題