protocol Test{
var t: Int {set get}
}
struct A: Test{
var t: Int
}
struct B: Test{
var t: Int
var s: String
}
let a = A(t: 1)
let b = B(t: 2, s: "1")
let c = a as Test
let d: [Test] = [a, b]
let e: [A] = [a, a]
let f = e as [Test]
let g = e as! [Test]
Run Code Online (Sandbox Code Playgroud)
"让f = e作为[测试],让g = e为![测试]"总是出错.我有一个功能,我必须发送[测试].将A转换为Test易于使用.但是当涉及到Array时,我必须遍历所有数据.有没有什么好方法可以将[A]转换为[Test].
不同代码的答案是正确的,但它也是重要的是要明白,为什么你不能只是重新解释数据,而不东西做一个O(n)的转换,虽然走,在一个盒子包装的每个元素.
[A]是一个元素大小为的数组A.所以,或多或少,A[1]是在内存位置A[0] + sizeof(A)(这不完全正确,但假装它是;它会使事情变得更简单).
[Test]必须能够保存符合协议的任何内容.它可能是大小A,可能是大小B,更大.为了实现这一点,它创建了一个包含"符合Test" 的框.所述盒是已知的尺寸,并且它可以具有到堆分配它指向的东西(或也许不是;取决于),但它不会成为相同的尺寸都A和B,所以布局[Test]在存储器必须与[A]or 的布局不同[B].
现在as [Test]可以做O(n)为你走,然后强制复制.或者它会延迟复制,直到你第一次修改某些东西,但它会复杂得多,它会在一个O(n)(可能是昂贵的,可能是内存分配)事件中埋下一个as感觉它应该是O(1)并且不分配内存.所以有理由不这样做.
有一天他们可能会这样做,以使调用者的事情变得更简单,但是性能和复杂性都有成本,因此今天它没有这样做,你需要自己做地图.
如果你想更深入地了解这些东西,有关这个盒子如何工作的更多细节(而不是"假装它比它更简单"),请参阅从WWDC 2016 了解Swift性能.
| 归档时间: |
|
| 查看次数: |
208 次 |
| 最近记录: |