【发布时间】:2021-05-20 23:15:15
【问题描述】:
我一直在使用 Apple 的神经网络工具,这意味着我一直在使用不安全的指针。我是和 C 一起长大的,我已经用 Swift 工作了很长一段时间,所以我用起来很舒服,但是关于它们的一件事让我完全被难住了。
我不明白为什么要从另一种不安全指针派生出任何努力。一般来说,它似乎应该是微不足道的,但不同类型的初始化器具体说明它们将采用什么样的输入,我很难弄清楚规则。
一个简单而具体的例子,也许是最让我难过的例子
// 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)
虽然我还没有找到任何关于不同种类背后理论的讨论,但我确实在this tutorial 中找到了线索。有一个图表比较了不同的类型,它说普通的旧UnsafePointer 是可跨步但不是集合,而UnsafeBufferPointer 是一个集合但不可跨步。
我理解不能跨步的集合的概念,比如集合。但这两种类型的不安全指针允许下标。它们就像常规数组一样工作,在我看来它们都是可跨步的集合。也许那里有我遗漏的微妙线索。
为什么不能从您可以从中获取UnsafePointer 的类型中获取UnsafeBufferPointer?
【问题讨论】:
-
"那为什么没有缓冲区指针初始化器呢?这是一个只有设计师才能告诉您原因的设计决策。无论如何,您可以从
UnsafeMutablePointer<Float>.allocate开始,而不是UnsafeMutableRawPointer.allocate,不是吗? -
另外,我有点担心你如何称呼
bindMemory。capacity是您要绑定的Float的实例数,而不是字节数。所以你可能应该通过100 / MemoryLayout<Float>.size来代替。 -
另请注意,您可以将
UnsafeMutableRawPointer直接转为UnsafeRawBufferPointer。这里的设计似乎是,如果你有一个原始指针,你可以 1) 使它不是原始的,或者 2) 使它成为一个缓冲区,如果你想做这两件事,你需要两个步骤。 -
很好地了解缓冲区的大小,非常感谢
标签: swift unsafe-pointers