在使用将字符串作为const char *
(将其转换为UnsafePointer<Int8>!
转换为Swift)的C库时,我注意到一些异常行为。传递String
可以按预期工作,但是String?
似乎破坏了输入。考虑一下我写的测试:
func test(_ input: UnsafePointer<UInt8>?) {
if let string = input {
print(string[0], string[1], string[2], string[3], string[4], string[5])
} else {
print("nil")
}
}
let input: String = "Hello"
test(input)
这将按预期方式工作,为输入字符串打印一个以UTF-8字节终止的空列表:
72 101 108 108 111 0
但是,如果我将输入更改为可选字符串,则它将变为:
let input: String? = "Hello"
我在结果中得到了一组完全不同的值(
176 39 78 23 1 0
),尽管我希望它是相同的。传递nil
可以正常工作。C库的功能允许
NULL
代替字符串,我有时也希望在Swift中将其传递,因此输入字符串是可选的是有意义的。这是Swift中的错误,还是Swift并非旨在处理这种情况?无论哪种方式,处理这种情况的最佳方法是什么?
编辑
它似乎与多个参数有关。 C函数:
void multiString(const char *arg0, const char *arg1, const char *arg2, const char *arg3) {
printf("%p: %c %c %c\n", arg0, arg0[0], arg0[1], arg0[2]);
printf("%p: %c %c %c\n", arg1, arg1[0], arg1[1], arg1[2]);
printf("%p: %c %c %c\n", arg2, arg2[0], arg2[1], arg2[2]);
printf("%p: %c %c %c\n", arg3, arg3[0], arg3[1], arg3[2]);
}
swift :
let input0: String? = "Zero"
let input1: String? = "One"
let input2: String? = "Two"
let input3: String? = "Three"
multiString(input0, input1, input2, input3)
结果是:
0x101003170: T h r
0x101003170: T h r
0x101003170: T h r
0x101003170: T h r
看来,Swift如何处理多个参数存在一个错误。
最佳答案
我没有发现任何有用的东西,如果这是期望的行为或仅仅是一个错误。
务实的解决方案可能只是使用这样的代理方法,但是您可能已经做了类似的事情。
func proxy(_ str: String?, _ functionToProxy: (UnsafePointer<UInt8>?) -> ()) {
if let str = str {
functionToProxy(str)
} else {
functionToProxy(nil)
}
}
proxy(input, test)
您是否测试了它是否可以在Swift 2中运行?他们改变了一些与Swift 3相关的内容:
https://github.com/apple/swift-evolution/blob/master/proposals/0055-optional-unsafe-pointers.md
关于swift - 当将可选的String转换为UnsafePointer时,Swift为什么会返回意外的指针?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39806995/