Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift-Cast泛型类型_Swift_Generics_Casting - Fatal编程技术网

Swift-Cast泛型类型

Swift-Cast泛型类型,swift,generics,casting,Swift,Generics,Casting,我试图将泛型类型强制转换为它的超类 class Foo : NSObject { } class Test<T> { let value: T init(_ value: T) { self.value = value } } let c = Test(Foo()) let v = c as Test<AnyObject> 数组在Swift中是特殊情况,因此能够具有这种行为。不幸的是,您无法用自己的类复制它 要获得类似的行为,您

我试图将泛型类型强制转换为它的超类

class Foo : NSObject {
}
class Test<T> {
    let value: T
    init(_ value: T) {
        self.value = value
    }
}

let c = Test(Foo())
let v = c as Test<AnyObject>

数组在Swift中是特殊情况,因此能够具有这种行为。不幸的是,您无法用自己的类复制它

要获得类似的行为,您可以为您的类型提供另一个
init
方法:

class Test<T> {
    let value: T
    init(_ value: T) {
        self.value = value
    }

    init<U>(other: Test<U>) {
        // in Swift 1.2 you will need as! here
        self.value = other.value as T
    }
}

let c = Test(Foo())
let v = Test<AnyObject>(other: c)  // this will work ok
类测试{
let值:T
初始值(u值:T){
自我价值=价值
}
初始(其他:测试){
//在Swift 1.2中,您将需要
self.value=其他.value作为T
}
}
设c=Test(Foo())
让v=Test(other:c)//这将正常工作

请注意,如果您想转换为不兼容的类型(替代方法是可失败的初始值设定项,也会有复杂问题),则这是不安全的(即在运行时断言)

编辑了我的答案以匹配,但恐怕它仍然不起作用。泛型类型在Swift中并不协变。看见你永远不知道,这可能会在未来的版本中发生变化(但不要指望它,这种变化会给支持它的语言带来痛苦的世界),你必须解释“这种变化会给支持它的语言带来痛苦的世界。”我需要一篇博文。@Rob,例如,六位数的C#声誉之神。这个问题给出了经典的C#协变数组prob。当然,Swift数组没有这个问题,因为它是值类型。但是展示了如果不非常小心地将协方差扩展到引用类型可能会导致悲剧。斯威夫特明智地将隐式提升到任意*当然是非法的,所以这通常不是一个问题(我肯定有他在Scala中描述的乐趣;但是[T]也是协方差的……),但我认为“关于值类型”这一点非常重要,确实可以解决许多问题。Swift在值类型和引用类型之间有一些非常清晰的分界线,这很有帮助。(但我并不反对这个问题是微妙和棘手的,最好是过于严格和宽松。)
let array1 = [Foo(), Foo()]
let array2 = array1 as [AnyObject]
class Test<T> {
    let value: T
    init(_ value: T) {
        self.value = value
    }

    init<U>(other: Test<U>) {
        // in Swift 1.2 you will need as! here
        self.value = other.value as T
    }
}

let c = Test(Foo())
let v = Test<AnyObject>(other: c)  // this will work ok