【发布时间】:2017-08-08 07:00:02
【问题描述】:
在某些情况下,您必须处理某种类型的结构,但上游 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 中重新解释结构的规范方法是什么?
【问题讨论】:
标签: swift swift3 unsafe-pointers