gpt4 book ai didi

swift - 在嵌套闭包中捕获值

转载 作者:搜寻专家 更新时间:2023-10-31 08:31:48 24 4
gpt4 key购买 nike

在嵌套闭包中使用捕获值的正确语法是什么?

我有以下使用 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 的相当困惑的编译器错误:

Cannot convert value of type 'UnsafeMutablePointer<_>' to expected argument type 'UnsafePointer!'

令人困惑,因为如果我将 crc32(crc, $0, size) 替换为 crc32(crc, $0, 4) ,编译器不会报错并且函数可以正确处理值大小为 4 个字节。

如何解决上述问题?

最佳答案

错误信息具有误导性。你的代码几乎是正确的,“唯一”的问题是 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) 那么“整数文字” 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
}

关于swift - 在嵌套闭包中捕获值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39917697/

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