- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
someData[start...stop]
返回一个 MutableRandomAccessSlice
的事实让我很苦恼。我的 someData
是一个 let
开始,那么为什么我想要一个 Mutable 的东西?为什么我不只得到一个 RandomAccessSlice
。但真正令人沮丧的是,它返回的 API 与原始源不兼容。对于 Data
,我可以使用 .withUnsafeBytes
,但对于这个后代则不然。以及如何将 Slice 变回 Data 也不清楚。没有采用其中之一的 init。
我可以使用 subdata(in:)
方法代替下标,但是如果我只想要一个行为类似于原始集合的子集合表示,那么下标有什么意义。另外,subdata
方法只能做开子范围,为什么下标既可以做闭也可以做开。这是他们还没有完全完成 Swift3 final 的东西吗?
最佳答案
请记住,您返回的 MutableRandomAccessSlice
是一个值 类型,而不是引用类型。这只是意味着你可以根据需要修改它,但这与你从中切出的东西无关:
let x = Data(bytes: [1,2,3]) // <010203>
var y = x[0...1]
y[0] = 2
x // <010203>
如果您查看 code ,您会注意到其目的是返回自定义切片类型:
public subscript(bounds: Range<Index>) -> MutableRandomAccessSlice<Data> {
get {
return MutableRandomAccessSlice(base: self, bounds: bounds)
}
set {
// Ideally this would be:
// replaceBytes(in: bounds, with: newValue._base)
// but we do not have access to _base due to 'internal' protection
// TODO: Use a custom Slice type so we have access to the underlying data
let arrayOfBytes = newValue.map { $0 }
arrayOfBytes.withUnsafeBufferPointer {
let otherData = Data(buffer: $0)
replaceBytes(in: bounds, with: otherData)
}
}
}
也就是说,自定义切片对于采用数据的函数来说仍然是 Not Acceptable 。不过,这与其他类型一致,例如 Array,它切片为 ArraySlice,而 ArraySlice 不能传递到需要数组的地方。这是设计使然(出于同样的原因,也可能是为了数据)。问题是切片“固定”了支持它的所有内存。因此,如果您从一个兆字节数据中取出一个 3 字节的切片并将其存储在一个 ivar 中,那么整个兆字节都必须保留。理论(根据与我交谈过的 Swift 开发人员的说法)是数组可能很大,因此您需要小心地对它们进行切片,而字符串通常要小得多,因此将字符串切片为字符串是可以的。
根据我目前的经验,您通常需要 subdata(in:)
。我对它的实验是它在速度上与切片非常相似,所以我相信它仍然是写时复制(但在我的初始测试中它似乎没有固定内存)。不过,到目前为止,我只在 Mac 上进行过测试。 iOS 设备上的性能差异可能更大。
关于swift - 数据 <-> MutableRandomAccessSlice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38063521/
someData[start...stop] 返回一个 MutableRandomAccessSlice 的事实让我很苦恼。我的 someData 是一个 let 开始,那么为什么我想要一个 Muta
我是一名优秀的程序员,十分优秀!