gpt4 book ai didi

swift - 在 Swift 中重新解释实体的正确方法是什么?

转载 作者:搜寻专家 更新时间:2023-11-01 07:10:01 24 4
gpt4 key购买 nike

在某些情况下,您必须处理某种类型的结构,但上游 API 要求您在其他地方通过指向另一种类型的指针来呈现它。

例如,Unix Bind 期望它的第二个参数是指向 sockaddr 的指针,而构造函数应该是 sockaddr_in

现在我坚持使用两层with*:

var sa = sockaddr_in(/* ... */)

withUnsafePointer(to: &sa) { _sa in
_sa.withMemoryRebound(to: sockaddr.self, capacity: 1) { __sa in
let err = bind(fd, __sa, socklen_t(saSize))
precondition(err == 0)
}
}

但是,我对这种方法的噪音感到灰心。当我在指针类型之间使用 unsafeBitCast 时:

bind(fd, unsafeBitCast(__sa, to: UnsafeMutablePointer<sockaddr>.self), socklen_t(saSize))

然后编译器警告我不要这样做,并建议求助于 withMemoryRebound

当我使用就地构造的指针时:

UnsafeMutablePointer(mutating: &sa).withMemoryRebound(to: sockaddr.self, capacity: 1) { _sa in
let err = bind(fd, _sa, socklen_t(saSize))
precondition(err == 0)
}

然后它和初始版本一样工作,并且让我们摆脱了一层嵌套。虽然看起来比with*还要虚弱。也不清楚,如果就地指针是正确的方法,为什么 withUnsafePointer 甚至存在。

话虽如此,在 Swift 中重新解释结构的规范方法是什么?

最佳答案

你的第一个方法是正确的,使用 withUnsafePointer()withMemoryRebound(),从各种示例中可以看出在 UnsafeRawPointer Migration 中提供,例如

In Swift 3, the user should explicitly rebind memory to a different type:

let result = withUnsafePointer(to: &addr) {
// Temporarily bind the memory at &addr to a single instance of type sockaddr.
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
connect(sock, $0, socklen_t(MemoryLayout<sockaddr_in>.stride))
}
}

另一种方法

UnsafeMutablePointer(mutating: &sa).withMemoryRebound(...) { ... }

在我看来很脆弱。 sa 作为 inout 参数传递给UnsafeMutablePointer() 的构造函数,但可能是临时存储的地址,并且不能保证当构造函数返回并且闭包时它仍然有效叫做。

关于swift - 在 Swift 中重新解释实体的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45561367/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com