2016-01-22 106 views
1

我有一個協議實現如下。如何從Swift協議中返回`[Self]`?

protocol DatabaseInjectable { 

    static func deriveObjectFromDBRow(row: [String]) -> Self? // Method - 1 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [Self]? // Method - 2 
} 

如果我成功與通信實施Method - 1這樣的:

static func deriveObjectFromDBRow(row: [String]) -> Self? { 

    ... 
} 

但我無法實現Method - 2這樣的:

static func collectAllObjectsForDatabaseAction(action: (WWDatabase) -> Void) -> [Self]? { 

    ... 
} 

有我得到一個錯誤像這樣:

'Self' is only available in a protocol or as the result of a method in a class; 

任何幫助返回陣列形式Self(它自己的類)會很好。

+1

儘管我自己回答了幾個*類似的問題(其中沒有一個我認爲回答你的*特定的問題),但我仍然發現了對'自我'的直覺的處理。也許有人可以寫一個明確的指南... – Grimxn

回答

1

如果你可以設置你的類final您可以通過類名稱替換Self

final class SampleClass: DatabaseInjectable { 
    init() { 
    } 
    static func deriveObjectFromDBRow(row: [String]) -> SampleClass? { 
     return SampleClass() 
    } 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [SampleClass]? { 
     let array = [SampleClass]() 
     return array 
    } 
} 
+0

它可能是一個解決方案,但我需要繼承它。因此我不能將它設置爲˚Final˚類。 – Goppinath

+0

很高興知道,thx男人,它幫助了我。 – tony508

0

有一個寫得很好的答案here,但總之,你可以定義你的協議,因爲這樣:


protocol DatabaseInjectable { 

    static func deriveObjectFromDBRow(row: [String]) -> DatabaseInjectable? // Method - 1 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [DatabaseInjectable]? // Method - 2 
} 
+0

謝謝,但我需要特定的類類型作爲返回類型。與Objective-C中的'instancetype'相同 – Goppinath

0

您可以在協議DatabaseInjectable中使用typealias,並將其用作符合協議的類中Self類型的別名。

class Database { 
    var desc : String = "Default" 
} 

protocol DatabaseInjectable { 
    typealias MySelf 

    static func deriveObjectFromDBRow(row: [String]) -> MySelf? 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [MySelf]? 
} 

class MyClass : DatabaseInjectable { 
    typealias MySelf = MyClass 

    static func deriveObjectFromDBRow(row: [String]) -> MySelf? { 
     return MyClass() 
    } 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [MySelf]? { 
     return [MyClass(), MyClass()] 
    } 
} 

/* example */ 
let closure : (Database) ->() = { print($0.desc) } 
var arr : [MyClass]? = MyClass.collectAllObjectsForDatabaseAction(closure) 
/* [MyClass, MyClass] */ 

然而,這裏的一個缺點是,你可以設置例如typealias MySelf = Int(在類中)並讓你的函數返回一個整數/整數數組(而不是self/[Self]),並且仍然符合你的協議。可能這是一個破壞交易的行爲。