Check if AnyObject is a generic type in Swift

Say I have a generic Bus class:

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

and I can create an instance of it:

 var myBus = Bus<String>() 

Now I have a function that takes a single AnyObject parameter and checks its type:

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

My problem is that I don’t see a way to check if there is an object type Bus and run the doSomething() function if it is of type Bus . Any help would be appreciated.


Change Protocols also do not seem to allow as they should.

 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>()) 
+5
source share
3 answers

The problem here is that you think of Bus as a specific thing. This is really not the case. Bus<String> is. Bus<Int> too. But Bus not, at least, not in the same sense. You need to know what T .

Indeed, you want to write something like this:

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

But if you try to use it, you will get an error message:

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

Unlike other languages, you cannot write checkType<String>(myBus) . But the following can do what you are looking for:

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

This fixes that T for any Bus<T> and will work correctly.

You may object that you do not want to indicate what T . However, instead, this leads to the question ... as soon as you find out that object is a kind of Bus , what are you going to do? Are you planning on calling methods on it or passing it as an argument to other functions? Most likely, what you are trying to achieve can be better done with a common function and protocol restrictions, instead of using AnyObject and casting.

+6
source

In swift 2.x, you can use the protocol to achieve this, since you tried without errors:

 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>()); 

exit:

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

This may or may not be useful to you specifically, since you seem to be using 1.2, but maybe someone who stumbles on this question will find it useful.

+2
source

You got it practically.

 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" 

I know that you don’t really want this, but it shows you need Swift.

0
source

Source: https://habr.com/ru/post/1214003/


All Articles