通用数组的Swift错误
我有一个非常简单的操场:通用数组的Swift错误,swift,generics,Swift,Generics,我有一个非常简单的操场: protocol MyProtocol {} struct MyType: MyProtocol {} class MyClass <T: MyProtocol> { func myFunction(array: [T]) { if let myArray = array as? [MyType] { println("Double!") } } } let instance =
protocol MyProtocol {}
struct MyType: MyProtocol {}
class MyClass <T: MyProtocol> {
func myFunction(array: [T]) {
if let myArray = array as? [MyType] {
println("Double!")
}
}
}
let instance = MyClass<MyType>()
let array = [MyType(), MyType()]
instance.myFunction(array)
但现在我无法将数组
转换为[MyType]
(当然,我知道这是Swift的静态类型规范。)
我想知道是什么问题。我对泛型的理解?还是因为斯威夫特语言的局限性?如果是的话,有没有办法做到这一点
提前感谢。Swift没有内置行为来推测性地将数组的内容从一种任意类型转换为另一种类型。它只会对已知具有子类型/超类型关系的两种类型执行此操作:
class A { }
class B: A { }
let a: [A] = [B(),B()]
// this is allowed - B is a subtype of A
let b = a as? [B]
let a: [AnyObject] = [1,2,3]
// this is allowed - NSNumber is a subtype of AnyObject
let b = a as? [NSNumber]
struct S1 { }
struct S2 { }
let a = [S1(),S1()]
// no dice - S2 is not a subtype of S1
let b = a as? [S2]
协议也没有帮助:
protocol P { }
struct S1: P { }
struct S2: P { }
let a = [S1(),S1()]
// still no good – just because S1 and S2 both conform to P
// doesn’t mean S2 is a subtype of S1
let b = a as? [S2]
您的示例基本上是最后一个示例的变体。您有一个类型为[T]
的数组,并且希望将其强制转换为[MyType]
。重要的是要了解您没有类型为[MyProtocol]
的数组。您的泛型类型T
是一种特定类型,必须实现MyProtocol
,但这不是一回事
要了解为什么不能从任何类型强制转换为任何其他类型,请尝试以下代码:
protocol P { }
struct S: P { }
let a: [P] = [S(),S()]
let b = a as? [S]
这将生成一个运行时错误:“致命错误:无法在不同大小的类型之间取消安全位广播”。这就暗示了为什么只能将数组从包含一个引用类型转换为一个子类型——这是因为所发生的事情只是从一个指针类型转换为另一个指针类型。这适用于超级/子类型类,但不适用于任意类、结构或协议,因为它们具有不同的二进制表示。子类型上的泛型不是父类型上相同泛型的子类型
Swift中的
[MyProtocol]
实际上转化为数组
(即泛型)。[MyType]
也是数组
的快捷方式。这就是为什么一个人不直接向另一个人施法。这又是一个很好的解释。虽然它让我觉得泛型类型似乎不是一个好的语言概念,因为使用它们只需要一个鸡蛋头。非常感谢您快速而详细的回答。这足以让我相信我不能这样做,但现在…我怎么能这样做呢?确切地说,我想要的(实际上,原始问题中的“Double!”
是它的跟踪,)是一个带有泛型的类,它的泛型类型是Double或Int。我想知道传递了什么类型,并将其转换为正确的数组类型。我试着用上面的方法来做这件事(正如你教我的,结果是不可能的。)你有什么想法吗?请原谅我的贪婪。也许是我自己通过实现协议的一些功能来解决的。谢谢。@Akkyie听起来你可能有一个enum的用例,谢谢你的快速回答。
protocol P { }
struct S: P { }
let a: [P] = [S(),S()]
let b = a as? [S]