2016-02-14 45 views
2

我想從字符串中讀取類並將其類型傳遞給泛型函數。不過好像沒有辦法實現這一目標:從字符串檢索鑄造類的類型

protocol Person { ... } 
class Student: Person { ... } 
class Teacher: Person { ... } 

func foo<SomePerson: Person>(param: String, type: SomePerson.Type) { ... } 

// Get class from string and pass class type to foo() 
let someClass = NSClassFromString("MyApp.Teacher") 
foo("someParam", type: someClass.dynamicType) 

嘗試這個,我得到一個錯誤:

Cannot invoke 'foo' with an argument list of type '(String, type: AnyClass.Type) 

它實際上是可以得到「真正的」型「教師,而不是泛型類型'AnyClass'並將其傳遞給foo()?這些類是在運行時從文件讀取的 - 所以在調用foo()時使用硬類名稱是不可能的。

感謝您的任何建議!

+0

,如果你知道真正的類型已經使用一個替代而不醜'NSClassFromString' - 如果你不知道的類型,然後你怎麼能確定它是Person的一個子類? – luk2302

+0

我不知道真正的類型...從文件中讀取類名(上例中的MyApp.Teacher)。存儲在文件中的類型通常是Person類的子類。 – kinkee

回答

3

如果Person是一類作爲原題寫着:

既然你正在爲編譯器的壽命相當困難,它需要是你一定要幫他一下。你必須確保調用函數之前的類型是正確的:

if let actualType = someClass as? Person.Type { 
    foo("someParam", type: actualType) 
} else { 
    // error handling here 
} 

其產生所需的工作代碼:

enter image description here


如果Person是一個協議:

你將有一個糟糕的一天。上述解決方案不起作用。至於我記得你唯一的選擇是檢查每一個可能的子類:

if let actualType = someClass as? Student.Type { 
    foo("someParam", type: actualType) 
} else if let actualType = someClass as? Teacher.Type { 
    foo("someParam", type: actualType) 
} 
// etc. 
+0

已經嘗試過幫助編譯器,這導致_Cannot無法用類型爲'(String,type:Person.Type)的參數列表調用'foo'_ – kinkee

+0

@kinkee您確定您使用了相同的確切代碼嗎?對我來說它工作正常 – luk2302

+0

對不起,我在我的示例源代碼中有一個錯字 - 「Person」是一個協議,而不是一個類。使用Person作爲類將會工作,但不幸的是,它們無法更改協議。 – kinkee