在嵌套闭包中使用捕获值的正确语法是什么?
我有以下工作代码,用于使用zlib
库从整数值计算CRC32。
func testCrc()
{
var x: UInt32 = 0xffffffff
let result = withUnsafePointer(to: &x, {
$0.withMemoryRebound(to: Bytef.self, capacity: 4) {
crc32(0, $0, 4)
}
})
XCTAssertEqual(0xffffffff, result)
}
我想创建可以从任何值计算CRC32的独立泛型函数。为了做到这一点,除了值本身,我还必须计算并传递它的大小,所以我不能使用显式大小 - 4 - 就像我在上面的代码中使用的那样。
但是我无法找到正确的语法来将计算出的大小传递给内部闭包。
func calculateCrc32<T>(_ crc: UInt, value: inout T) -> UInt
{
let size = MemoryLayout.size(ofValue: value)
let result = withUnsafePointer(to: &value, {
$0.withMemoryRebound(to: Bytef.self, capacity: size) {
crc32(crc, $0, size) // error
}
})
return result
}
上面的代码显示参数$0
的编译器错误相当混乱:
无法转换'UnsafeMutablePointer&lt; _&gt;'类型的值预期 参数类型'UnsafePointer!'
令人困惑,因为如果我用crc32(crc, $0, size)
编译器替换crc32(crc, $0, 4)
并不抱怨,并且函数适用于大小为4字节的值。
如何解决上述问题?
答案 0 :(得分:4)
错误消息具有误导性。你的代码几乎是正确的
&#34;仅&#34;问题是crc32()
需要的最后一个参数
是uInt
:
func calculateCrc32<T>(_ crc: UInt, value: inout T) -> UInt
{
let size = MemoryLayout.size(ofValue: value)
let result = withUnsafePointer(to: &value, {
$0.withMemoryRebound(to: Bytef.self, capacity: size) {
crc32(crc, $0, uInt(size))
}
})
return result
}
如果你拨打crc32(crc, $0, 4)
,那么&#34;整数字面值&#34; 4
作为最后一个参数传递,编译器推断其类型
作为uInt
匹配函数定义。
它不会与crc32(crc, $0, size)
一起编译,因为Swift会这样做
不是隐式地在类型之间转换。
或者,使用numericCast()
,这是一个泛型函数,可以在不同的有符号和无符号整数类型(以及溢出时的陷阱)之间进行转换。
我还建议改为使用该值的局部变量副本
使用inout
参数,这使得更容易调用
功能:
func calculateCrc32<T>(_ crc: UInt, value: T) -> UInt {
var value = value
let size = MemoryLayout.size(ofValue: value)
let result = withUnsafePointer(to: &value, {
$0.withMemoryRebound(to: Bytef.self, capacity: size) {
crc32(crc, $0, numericCast(size))
}
})
return result
}