来自Swift is运算符的意外结果

来自Swift is运算符的意外结果,swift,generics,types,Swift,Generics,Types,鉴于下面的代码,我正在试图理解这段代码哪里出错了。 在下面的代码中,我试图在UITabBarController的ViewController属性中找到特定类的UIViewController,该属性声明为: var viewControllers: [AnyObject]? 因此,我定义了两个UIViewController子类,并将它们填充到viewControllers数组中,并运行两个不同的方法来提取它们“viewControllerInfo:”viewControllerInfo2“

鉴于下面的代码,我正在试图理解这段代码哪里出错了。 在下面的代码中,我试图在UITabBarController的ViewController属性中找到特定类的UIViewController,该属性声明为:

var viewControllers: [AnyObject]?
因此,我定义了两个UIViewController子类,并将它们填充到viewControllers数组中,并运行两个不同的方法来提取它们“viewControllerInfo:”viewControllerInfo2“。 两者产生相同的结果

我的理解是:
如果设x为?T
将计算true,如果x为同一类,则将其指定为“T”类型。 就像
如果x是T
一样

你知道为什么评估会这样吗

class VC1: UIViewController {}

class VC2: UIViewController {}

let tabBar = UITabBarController()
tabBar.viewControllers = [VC1(), VC2()]

extension UITabBarController {

    public func viewControllerInfo<T: UIViewController>(ofType: T.Type) -> (viewController: T,index: Int)? {
        if let tabViewControllers = self.viewControllers{
            for  (idx, maybeVCTypeT) in enumerate(tabViewControllers) {
                if let viewController = maybeVCTypeT as? T {
                    return (viewController, idx)
                }
            }

        }
        return nil
    }

    public func viewControllerInfo2<T: UIViewController>(ofType: T.Type) -> (viewController: T,index: Int)? {
        if let tabViewControllers = self.viewControllers{
            for  (idx, maybeVCTypeT) in enumerate(tabViewControllers) {
                if maybeVCTypeT is T {
                    return (maybeVCTypeT as! T, idx)
                }
            }

        }
        return nil
    }


}
我怀疑enumerate(x),因为如果没有它,我会得到预期的结果:

if testVC1 is VC2 {
    println("\(testVC1) is \(VC2.self)")
}
上述代码产生一个警告:

从“VC1”转换到不相关类型“VC2”总是失败 这就是我试图通过enumerate实现的目标

*****************编辑*****************

实际上,我对enumerate的怀疑在运行了下面运行得很好的代码之后就消失了

let myArray: [AnyObject] = [VC2(), VC1()]
for (idx, x) in enumerate(myArray) {
    println(x)
    if let xAsVC1 = x as? VC1 {
        println("\(x) is supposed to be \(VC1.self)")
//"<__lldb_expr_155.VC1: 0x7fc12a9012f0> is supposed to be __lldb_expr_155.VC1"

    }

    if x is VC2 {
        println("\(x) is supposed to be \(VC2.self)")
//"<__lldb_expr_155.VC2: 0x7fc12a900fd0> is supposed to be __lldb_expr_155.VC2"

    }
}
让myArray:[AnyObject]=[VC2(),VC1()]
用于枚举(myArray)中的(idx,x){
println(x)
如果设xAsVC1=x为?VC1{
println(“\(x)应该是\(VC1.self)”)
//“应该是u lldb_expr_155.VC1”
}
如果x是VC2{
println(“\(x)应该是\(VC2.self)”)
//“应该是u lldb_expr_155.VC2”
}
}

这似乎是由泛型约束引起的,我认为这是一个bug()。删除泛型约束或将其设置为非ObjC类(例如
AnyObject
)似乎可以修复它:

public func viewControllerInfo<T>(ofType: T.Type) -> (viewController: T,index: Int)? {
与:


这似乎是可行的。

这似乎是由泛型约束引起的,我认为这是一个bug()。删除泛型约束,或将其设置为非ObjC类(例如
AnyObject
)似乎可以修复它:

public func viewControllerInfo<T>(ofType: T.Type) -> (viewController: T,index: Int)? {
与:


这似乎是可行的。

我只是尝试了同样的方法,但使用IsKindof类检查,我得到了相同的VC1类对象,用于测试VC1和VC2…有趣的是,这段代码在扩展之外工作。我不确定为什么是这样奇怪;我看到它按照您的预期工作,w/IsKindof类。我得到了VC1和VC2。她e是我的游乐场。我得到了VC1,VC2,VC1,VC2。测试w/6.4这是同一个问题吗?你完全正确,在签名上有UIViewController约束是什么把它搞砸了:)谢谢@RobI我想这本质上是同一个问题,我从来都不知道这种行为。对我来说,这似乎是一个苹果bug,不是吗?我只是尝试了同样的,但没有Iskindof类检查,我得到了相同的VC1类对象,反对使用VC1和VC2进行测试…有趣的是,这段代码在扩展之外工作。不知道为什么是这样奇怪;我看到它像你期望的那样工作w/Iskindof类。我得到了VC1和VC2。这是我的游乐场。我得到了VC1,VC2,VC1,VC2。测试w/6.4Co这会是同一个问题吗?你完全正确,在签名上使用UIViewController约束是把事情搞砸了:)谢谢@Rob我认为这本质上是同一个问题,我从来都不知道这种行为。对我来说,这好像是一个苹果bug,不是吗?
            if maybeVCTypeT is T {
            if maybeVCTypeT.isKindOfClass(T) {