【问题标题】:Down casting multiple protocol Array<protocol<P1, P2>> to Array<P1>向下转换多个协议 Array<protocol<P1, P2>> 到 Array<P1>
【发布时间】:2015-12-13 23:28:42
【问题描述】:

所以我有两个数组

var arrayOne:Array<protocol<P1,P2>>
var arrayTwo:Array<P1>

其中 P1 和 P2 是协议。

问题是如何进行向下转换操作

arrayTwo = arrayOne as Array<P1>

我从 Xcode 得到的是:

Cannot convert value of type 'Array<protocol<P1, P2>>' to specified type 'Array<P1>'

【问题讨论】:

    标签: arrays swift protocols swift2.1


    【解决方案1】:

    你需要转换数组的元素,而不是数组本身。

    arrayTwo = arrayOne.map { $0 as P1 }
    

    或者正如 MartinR 所说,甚至不需要强制转换元素。

    arrayTwo = arrayOne.map { $0 }
    

    【讨论】:

    • 有趣的是,即使通过arrayTwo = arrayOne.map { $0 } 的“身份映射”进行赋值也可以编译代码。这很奇怪,因为向上转换整个数组确实适用于子/超类,如stackoverflow.com/questions/30169839/…
    • @MartinR Element 的类型从 arrayTwo 声明中得知,所以我认为这是“正常”
    • @user3441734 这可能是“正常的”,但它绝对不直观。这就是 Swift 应该有的样子。也没有任何理由要求map
    • @MartinR hm... 可能更清楚地看到 'typealias U = P1 var arrayTwo: Array = arrayOne.map{ (e) -> U in e }' 这样没有强制转换,但是转换
    • @user3441734 清洁度如何?正如 MartinR 所说,甚至不需要铸造。
    【解决方案2】:
    protocol P1{}
    struct A: P1{}
    // everybody knows, that
    let a = A()
    // (1)
    let p: P1 = a
    // or (2)
    let p1 = a as P1
    
    let arr: Array<A> = []
    // has type
    print(arr.dynamicType) // Array<A>
    // (3) the array is converted to different type here !!
    let arr1: Array<P1> = arr.map{ $0 }
    print(arr1.dynamicType) // Array<P1>
    
    // arr and arr1 are differnet types!!!
    // the elements of arr2 can be down casted as in (1) or (2)
    // (3) is just an equivalent of
    typealias U = P1
    let arr3: Array<U> = arr.map { (element) -> U in
        element as U
    }
    print(arr3.dynamicType) // Array<P1>
    
    
    // the array must be converted, all the elements are down casted in arr3 from A to P1
    // the compiler knows the type so ii do the job like in lines (1) or (2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      • 1970-01-01
      • 2018-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      相关资源
      最近更新 更多