Swift Element 的通用集合无法转换为 Any 的集合
Swift generic collection of Element cannot convert to collection of Any
我遇到了一个我不明白的问题。
在我的项目中,我想用一些自定义方法(比如从服务器更新)来制作元素集合。但是,当我尝试将所有这些集合分组到一个数组中时,出现错误:“无法将类型 MyCollection<someElement>
的值转换为预期的参数类型 MyCollection<Any>
”
我不明白的是,与 Array 相同的代码正在运行...Array 不是集合?
// My collection which would contain an update method
class MyCollection<Element> {
var object:Element? = nil
}
let x = MyCollection<Int>()
var list = [MyCollection<Any>]()
list.append(x) //Cannot convert value of type 'MyCollection<In>' to expected argument type 'MyCollection<Any>'
let a = Array<Int>()
var lista = [Array<Any>]()
lista.append(a) //Doesn't get error at all...
我知道我可以使用特定类型的数组来执行此操作,但是通过将所有 MyCollection 分组到一个数组中,我希望使用如下代码:
func update() {
for e in list { // array of MyCollection<Any>
e.update()
}
}
提前感谢您的帮助 ;)
能够从SomeType<Subtype>
转换为SomeType<Supertype>
称为协方差。在 Swift、Array<T>
is covariant on T
by "compiler magic", and you can't do the same for your own types.
The type checker hardcodes conversions from Array to Array if there is a conversion from T to U. Similar rules exist for Optional and Dictionary. There's no mechanism for doing this with your own types.
您自己的泛型类型总是不变的,这意味着只要 T
和 U
是不同的类型,就永远不会在 SomeType<T>
到 SomeType<U>
之间进行转换.
让我们想象一下如果允许 MyCollection
上的转换会发生什么。你可以这样做:
let myCollectionInt = MyCollection<Int>()
let myCollectionAny: MyCollection<Any> = myCollectionInt // suppose you can do this
myCollectionAny.object = "string" // myCollectionAny.object is of type Any?, so this should be ok
我们已经将myCollectionAny.object
设置为“string”,但是MyCollection
是引用类型,所以myCollectionInt.object
也应该是“string”。但是 myCollectionInt.object
是 Int?
!
当然这 type-unsafety 也是数组的一个问题,但是语言设计者已经决定转换数组是一件很常见的事情,不允许这样做会弊大于利。
我遇到了一个我不明白的问题。
在我的项目中,我想用一些自定义方法(比如从服务器更新)来制作元素集合。但是,当我尝试将所有这些集合分组到一个数组中时,出现错误:“无法将类型 MyCollection<someElement>
的值转换为预期的参数类型 MyCollection<Any>
”
我不明白的是,与 Array 相同的代码正在运行...Array 不是集合?
// My collection which would contain an update method
class MyCollection<Element> {
var object:Element? = nil
}
let x = MyCollection<Int>()
var list = [MyCollection<Any>]()
list.append(x) //Cannot convert value of type 'MyCollection<In>' to expected argument type 'MyCollection<Any>'
let a = Array<Int>()
var lista = [Array<Any>]()
lista.append(a) //Doesn't get error at all...
我知道我可以使用特定类型的数组来执行此操作,但是通过将所有 MyCollection 分组到一个数组中,我希望使用如下代码:
func update() {
for e in list { // array of MyCollection<Any>
e.update()
}
}
提前感谢您的帮助 ;)
能够从SomeType<Subtype>
转换为SomeType<Supertype>
称为协方差。在 Swift、Array<T>
is covariant on T
by "compiler magic", and you can't do the same for your own types.
The type checker hardcodes conversions from Array to Array if there is a conversion from T to U. Similar rules exist for Optional and Dictionary. There's no mechanism for doing this with your own types.
您自己的泛型类型总是不变的,这意味着只要 T
和 U
是不同的类型,就永远不会在 SomeType<T>
到 SomeType<U>
之间进行转换.
让我们想象一下如果允许 MyCollection
上的转换会发生什么。你可以这样做:
let myCollectionInt = MyCollection<Int>()
let myCollectionAny: MyCollection<Any> = myCollectionInt // suppose you can do this
myCollectionAny.object = "string" // myCollectionAny.object is of type Any?, so this should be ok
我们已经将myCollectionAny.object
设置为“string”,但是MyCollection
是引用类型,所以myCollectionInt.object
也应该是“string”。但是 myCollectionInt.object
是 Int?
!
当然这 type-unsafety 也是数组的一个问题,但是语言设计者已经决定转换数组是一件很常见的事情,不允许这样做会弊大于利。