我无法弄清楚为什么要从一个不安全指针中派生出另一种类型的不安全指针需要付出任何努力。总的来说,看起来这应该是微不足道的,但是不同类型的初始化器都对其输入进行了特定的限制,我很难弄清楚规则。
一个简单和具体的例子,也许是让我感到最困惑的一个。
// The neural net components want mutable raw memory, and it's easier
// to build them up from the bottom, so: raw memory
let floats = 100
let bytes = floats * MemoryLayout<Float>.size
let raw = UnsafeMutableRawPointer.allocate(byteCount: bytes, alignment: MemoryLayout<Float>.alignment)
// Higher up in the app, I want to use memory that just looks like an array
// of Floats, to minimize the ugly unsafe stuff everywhere. So I'll use
// a buffer pointer, and that's where the first confusing thing shows up:
// This won't work
// let inputs = UnsafeMutableBufferPointer<Float>(start: raw, count: floats)
// The initializer won't take raw memory. But it will take a plain old
// UnsafePointer<Float>. Where to get that? you can get it from the raw pointer
let unsafeMutablePointer = raw.bindMemory(to: Float.self, capacity: floats)
// Buf if that's possible, then why wouldn't there be a buffer pointer initializer for it?
// Of course, with the plain old pointer, I can get my buffer pointer
let inputs = UnsafeMutableBufferPointer(start: unsafeMutablePointer, count: floats)
尽管我没有找到任何关于这些不同种类背后理论的讨论,但我在这个教程中找到了一个提示。其中有一个比较不同类型的图表,它说普通的
UnsafePointer
可以步进但不是集合,而UnsafeBufferPointer
是集合但不能步进。我理解集合无法步进的概念,例如set。但这两种类型的不安全指针允许下标。它们像常规数组一样工作,这听起来就像它们都是可步进的集合。也许我漏掉了某个微妙的提示。
为什么不能从你可以从中获取
UnsafePointer
的类型得到UnsafeBufferPointer
呢?
UnsafeMutablePointer<Float>.allocate
开始,而不是从UnsafeMutableRawPointer.allocate
开始,对吧? - SweeperbindMemory
。capacity
是您想要绑定的Float
实例数,而不是字节数。因此,您应该传递100 / MemoryLayout<Float>.size
。 - SweeperUnsafeMutableRawPointer
转换为UnsafeRawBufferPointer
。这里的设计似乎是,如果您有一个原始指针,您可以选择1)使其不是原始的,或2)将其变成缓冲区。如果您想同时执行这两个操作,则需要两个步骤。 - Sweeper