繁体   English   中英

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

[英]Check if AnyObject is of generic type in Swift

假设我有通用类Bus

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

我可以创建它的实例:

var myBus = Bus<String>()

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

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

我的问题是我看不到检查object是否为Bus类型的方法,如果它是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>())

这里的问题是你认为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)

这解决了任何Bus<T> T是什么,并将正常工作。

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

在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,但也许遇到这个问题的其他人会发现它很有用。

你几乎得到了它。

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的需求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM