检查AnyObject是否是Swift中的泛型类型

Sai*_*ira 5 generics xcode ios swift

假设我有通用类Bus:

class Bus<T> {
    func doSomething() {}
}
Run Code Online (Sandbox Code Playgroud)

我可以创建它的实例:

var myBus = Bus<String>()
Run Code Online (Sandbox Code Playgroud)

现在我有一个函数,它接受一个参数AnyObject并测试它的类型:

func checkType(object: AnyObject) {
    if let foo = object as? String {
        println("string")
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是我看不到一种方法来检查是否object是类型Bus和运行函数,doSomething()如果它是类型Bus.任何帮助,将不胜感激.


编辑:协议似乎也没有解决这个问题.

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>())
Run Code Online (Sandbox Code Playgroud)

Air*_*ity 6

这里的问题是你认为Bus具体的事情.它真的不是. Bus<String>是. Bus<Int>也是.但Bus事实并非如此,至少在同一意义上并非如此.你需要知道什么T是.

真的,你想要的是写这样的东西:

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

但是如果你尝试使用它,你会收到一个错误:

// error: Argument for generic parameter 'T' could not be inferred.
checkType(myBus)
Run Code Online (Sandbox Code Playgroud)

与其他语言不同,你不能写checkType<String>(myBus).但以下可能会做你想要的:

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

checkType(myBus,String.self)
Run Code Online (Sandbox Code Playgroud)

这可以解决T任何问题,Bus<T>并且可以正常工作.

你可能会反对你不想指定是什么T.然而,相反,这导致了一个问题......一旦你发现这object是某种形式Bus,你打算做什么呢?您是否计划在其上调用方法,或将其作为参数传递给其他函数?使用通用函数和协议约束可以更好地完成您尝试实现的目标,而不是使用AnyObject和转换.


jer*_*e10 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"
Run Code Online (Sandbox Code Playgroud)

我知道这并不是您真正想要的,但它显示了 Swift 的需求。