2015-02-23 54 views
5

比方說,我有泛型類總線檢查AnyObject是通用型的雨燕

class Bus<T> { 
    func doSomething() {} 
} 

,我可以創建它的實例:

var myBus = Bus<String>() 

現在我有一個函數需要AnyObject的一個參數並測試它的類型:

func checkType(object: AnyObject) { 
    if let foo = object as? String { 
     println("string") 
    } 
} 

我的問題是,我看不到一種方法來檢查objectBus類型,如果它是Bus類型,則運行功能doSomething()。任何幫助,將不勝感激。


編輯:協議也似乎沒有解決這個問題,他們應該的樣子。

import Foundation 

@objc protocol BusProtocol { 
    func doSomething() -> Void 
} 

class Bus<T> : BusProtocol { 
    func doSomething() -> Void { 
     println("asdf") 
    } 
} 

func checkType(object: AnyObject) { 
    if let foo = object as? Bus<AnyObject> { 
     foo.doSomething() // no match 
    } 
    if let foo = object as? Bus<Any> { 
     foo.doSomething() // no match 
    } 
    if let foo = object as? Bus<String> { 
     foo.doSomething() // prints "asdf" 
    } 
    if let foo = object as? BusProtocol { 
     foo.doSomething() // SIGABRT -- -[SwiftObject doesNotRecognizeSelector:] 
    } 
} 

checkType(Bus<String>()) 
+1

你使用'@ objc'編輯示例不會出現與Swift 1.2的段錯誤 - 但它確實會給你一個錯誤(這可能是以前的問題,處理得不那麼優雅)泛型類中的方法不能' @ objc'(因爲Objective-C不支持泛型)。但是,如果你在協議上放棄了'@ objc'限定符,它就像希望的一樣工作(再次使用Swift 1.2,它引入了更多的協議和'as'功能) – 2015-02-23 17:15:27

回答

0

你幾乎得到了它。

func checkType(object: AnyObject) { 
    if let foo = object as? Bus<AnyObject> { 
     print("Got here") 
    } else { 
     print("Fail") 
    } 
} 

let bus = Bus<String>() 
checkType(bus) // Fail 

let otherBus = Bus<AnyObject>() 
checkType(otherBus) // "Got Here" 

我知道這不是你想要的,但它顯示了Swift需要什麼。

+0

這是行不通的,我試了一下。它拋出'泛型類型的參數'T'無法被推斷出來' – 2015-02-23 15:39:22

+0

哦,我明白你現在要問什麼。你需要知道公交車本身是什麼?你關心巴士包含什麼類型? – jervine10 2015-02-23 15:40:30

+1

我只需要檢查對象是否是某種'Bus'並且如果是的話就可以運行'doSomething()'。 – 2015-02-23 15:42:28

6

這裏的問題是你認爲Bus是一個具體的事情。它確實不是。 Bus<String>是。 Bus<Int>也是。但是Bus不是,至少不是相同的意義。你需要知道什麼是T

真的,你想要的是寫的是這樣的:

func checkType<T>(object: AnyObject) { 
    if let foo = object as? Bus<T> { 
     println("Bus<T>") 
    } 
} 

但是,如果你嘗試使用它,你會得到一個錯誤:

// error: Argument for generic parameter 'T' could not be inferred. 
checkType(myBus) 

不像在其他語言中,你不能寫checkType<String>(myBus)。但下面可能做你要找的內容:

func checkType<T>(object: AnyObject, T.Type) { 
    if let foo = object as? Bus<T> { 
     println("Bus<T>") 
    } 
} 

checkType(myBus,String.self) 

這解決什麼T爲任何Bus<T>和將正常工作。

您可能會反對,您不想指定T是什麼。然而,相反,這導致了一個問題......一旦你發現object是某種Bus,那麼你打算怎麼做?你打算調用它的方法,還是將它作爲參數傳遞給其他函數?使用通用函數和協議約束可能會更好地實現您嘗試實現的目標,而不是使用AnyObject和投射。

2

在swift 2。X可以使用協議來實現這一點,因爲你試圖在沒有錯誤:

protocol Busish { 
    func doSomething() -> Void 
} 

class Bus<T> : Busish { 
    func doSomething() { 
    print(self) 
    } 
} 

func with_any_bus(obj:AnyObject) { 
    if let b = obj as? Busish { 
    b.doSomething() 
    } 
} 

with_any_bus(Bus<Int>()); 
with_any_bus(Bus<String>()); 

輸出:

swiftblah.Bus<Swift.Int> 
swiftblah.Bus<Swift.String> 

這可能是或可能不是幫助你具體地,因爲你似乎可以用1.2 ,但也許別人在這個問題上發現它會很有用。

+0

感謝您的建議。我能寫一個空的協議來檢查一個類是否是我的泛型類。沒有功能,我只是想要一張支票。 – 2016-01-09 03:53:33