与泛型数组的Swift错误 [英] Swift error with generic array

查看:83
本文介绍了与泛型数组的Swift错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的操场:

  protocol MyProtocol {} 

struct MyType:MyProtocol {}

class MyClass< T:MyProtocol> {
func myFunction(array:[T]){
如果让myArray = array as? [MyType] {
println(Double!)
}
}
}

让instance = MyClass< MyType>()

let array = [MyType(),MyType()]

instance.myFunction(array)

如果 MyType不是'T'的子类型 c $ c>行。不过,我认为, MyType T 是兼容的。



如果让语句修改了,它实际上可以工作:

 如果let first = array.first as? MyType 

但现在我无法投射数组<$ code >到 [MyType] (当然,我知道它是Swift的静态类型规范。)



问题是什么。我对泛型的理解?或者它是Swift语言的限制?如果是这样,有没有办法做到这一点?



预先致谢。

解决方案

Swift没有内建行为来推测性地将数组的内容从一个任意类型转换为另一个类型。它只会为两种类型做它,它知道它有一个子类型/超类型关系:

  class A {} 
B类:A {}
让a:[A] = [B(),B()]
//这是允许的 - B是A
的子类型let b = a如? [B]

让a:[AnyObject] = [1,2,3]
//这是允许的 - NSNumber是AnyObject的子类型
let b = a as ? [NSNumber]

struct S1 {}
struct S2 {}

let a = [S1(),S1()]
// no骰子 - S2不是S1的子类型b $ b让b = a as? [S2]

该协议并没有帮助:

  protocol P {} 
struct S1:P {}
struct S2:P {}

let a = [ S1(),S1()]
//仍然不好 - 仅仅因为S1和S2都符合P
//并不意味着S2是S1的子类型
let b =一个? [S2]

您的示例基本上是最后一个的变体。你有一个 [T] 类型的数组,并且你想把它转换为 [MyType] 。理解你 有一个类型为 [MyProtocol] 的数组非常重要。您的泛型类型 T 是一个特定的类型,它必须实现 MyProtocol ,但这不是一回事。 p>

为了明白为什么你不能从任何类型转换到任何其他类型,请尝试下面的代码:

  protocol P {} 
struct S:P {}

let a:[P] = [S(),S()]
让b = a as? [S]

这会产生一个运行时错误:致命错误:不能unsafeBitCast类型不同尺寸。这给出了一个暗示,为什么你只能将一个数组从一个引用类型转换为一个子类型 - 这是因为发生的事情只是从一个指针类型转换到另一个指针类型。这将适用于super / subtype类,但不适用于任意类,结构或协议,因为它们具有不同的二进制表示形式。


I have a very simple playground:

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)

Then it says "MyType is not a subtype of 'T'" on the if let line. Well, I think, however, MyType and T are compatible.

When I modified the if let statement, it actually works:

if let first = array.first as? MyType

But now I can't cast array to [MyType] (Sure, I know it is Swift's static typing specification.)

I'm wondering what the problem is. My understanding about Generics? Or is it Swift language's limitation? If so, is there any way to do like this?

Thanks in advance.

解决方案

Swift doesn’t have builtin behaviour to speculatively convert an array’s contents from one arbitrary type to another. It will only do this for two types that it knows have a subtype/supertype relationship:

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]

The protocol doesn’t help either:

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]

Your example is basically a variant of this last one. You have an array of type [T], and you want to cast it to [MyType]. It’s important to understand that you do not have an array of type [MyProtocol]. Your generic type T is a specific type, which has to implement MyProtocol, but that’s not the same thing.

To see why you can’t just cast from any type to any other type, try this code:

protocol P { }
struct S: P { }

let a: [P] = [S(),S()]
let b = a as? [S]

This will generate a runtime error: "fatal error: can't unsafeBitCast between types of different sizes". This gives a hint as to why you can only cast an array from containing one reference type to a subtype – it’s because what is happening is just a bit cast from one pointer type to another. This will work for super/subtype classes, but not for arbitrary classes, structs, or protocols, as they have different binary representations.

这篇关于与泛型数组的Swift错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆