Swift 阻止语法推断类型失败
Swift block syntax failure to infer type
谁能解释为什么这个带有隐式 return
的单行块可以编译:
let r = withUnsafePointer(&msg) {
dn_expand(UnsafePointer([=11=]), eomorig: UnsafePointer([=11=]).advancedBy(msg.count), comp_dn: UnsafePointer([=11=]).advancedBy(offset), exp_dn: &buf, length: buf.count)
}
但是这个版本进行了重构,唯一的区别是避免多次调用 UnsafePointer([=15=])
而不是:
let s = withUnsafePointer(&msg) {
let p = UnsafePointer([=12=])
return dn_expand(p, eomorig: p.advancedBy(msg.count), comp_dn: p.advancedBy(offset), exp_dn: &buf, length: buf.count)
}
错误信息:
Cannot convert value of type 'inout [UInt8]' (aka 'inout Array<UInt8>') to expected argument type 'inout _'
被调用的 dn_function
只是 libresolv
中 dn_expand
的简单包装:
public static func dn_expand(msg: UnsafePointer<UInt8>, eomorig: UnsafePointer<UInt8>, comp_dn: UnsafePointer<UInt8>, exp_dn: UnsafeMutablePointer<CChar>, length: Int) -> Int {
return Int(res_9_dn_expand(msg, eomorig, comp_dn, exp_dn, Int32(length)))
}
如评论中所述,withUnsafePointer()
不是
获取指向元素存储的指针的正确方法。它编译,但是
给出意想不到的结果,如下例所示:
var msg: [UInt8] = [1, 2, 3, 4]
func foo(x: UnsafePointer<UInt8>) {
print(x[0])
}
withUnsafePointer(&msg) {
foo(UnsafePointer([=10=]))
}
这会打印 "random" 个数字,但不是预期的 1
。正确的
方法是在数组上调用 withUnsafeBufferPointer()
方法:
msg.withUnsafeBufferPointer {
foo([=11=].baseAddress)
}
你的情况是
let r = msg.withUnsafeBufferPointer {
dn_expand([=12=].baseAddress, eomorig: [=12=].baseAddress + [=12=].count, ...)
}
这里闭包的 return 类型是自动推断的,因为
这是一个 "single-expression" 闭包。如果闭包包含更多
比一个表达式,你必须指定它的类型:
let r = msg.withUnsafeBufferPointer { bufPtr -> Int in
let p = bufPtr.baseAddress
return dn_expand(p, eomorig: p + msg.count, ...)
}
或者让编译器从 上下文推断 return 类型:
let r: Int = msg.withUnsafeBufferPointer { bufPtr in
let p = bufPtr.baseAddress
return dn_expand(p, eomorig: p + msg.count, ...)
}
谁能解释为什么这个带有隐式 return
的单行块可以编译:
let r = withUnsafePointer(&msg) {
dn_expand(UnsafePointer([=11=]), eomorig: UnsafePointer([=11=]).advancedBy(msg.count), comp_dn: UnsafePointer([=11=]).advancedBy(offset), exp_dn: &buf, length: buf.count)
}
但是这个版本进行了重构,唯一的区别是避免多次调用 UnsafePointer([=15=])
而不是:
let s = withUnsafePointer(&msg) {
let p = UnsafePointer([=12=])
return dn_expand(p, eomorig: p.advancedBy(msg.count), comp_dn: p.advancedBy(offset), exp_dn: &buf, length: buf.count)
}
错误信息:
Cannot convert value of type 'inout [UInt8]' (aka 'inout Array<UInt8>') to expected argument type 'inout _'
被调用的 dn_function
只是 libresolv
中 dn_expand
的简单包装:
public static func dn_expand(msg: UnsafePointer<UInt8>, eomorig: UnsafePointer<UInt8>, comp_dn: UnsafePointer<UInt8>, exp_dn: UnsafeMutablePointer<CChar>, length: Int) -> Int {
return Int(res_9_dn_expand(msg, eomorig, comp_dn, exp_dn, Int32(length)))
}
如评论中所述,withUnsafePointer()
不是
获取指向元素存储的指针的正确方法。它编译,但是
给出意想不到的结果,如下例所示:
var msg: [UInt8] = [1, 2, 3, 4]
func foo(x: UnsafePointer<UInt8>) {
print(x[0])
}
withUnsafePointer(&msg) {
foo(UnsafePointer([=10=]))
}
这会打印 "random" 个数字,但不是预期的 1
。正确的
方法是在数组上调用 withUnsafeBufferPointer()
方法:
msg.withUnsafeBufferPointer {
foo([=11=].baseAddress)
}
你的情况是
let r = msg.withUnsafeBufferPointer {
dn_expand([=12=].baseAddress, eomorig: [=12=].baseAddress + [=12=].count, ...)
}
这里闭包的 return 类型是自动推断的,因为 这是一个 "single-expression" 闭包。如果闭包包含更多 比一个表达式,你必须指定它的类型:
let r = msg.withUnsafeBufferPointer { bufPtr -> Int in
let p = bufPtr.baseAddress
return dn_expand(p, eomorig: p + msg.count, ...)
}
或者让编译器从 上下文推断 return 类型:
let r: Int = msg.withUnsafeBufferPointer { bufPtr in
let p = bufPtr.baseAddress
return dn_expand(p, eomorig: p + msg.count, ...)
}