swift - UnsafePointer<UInt8> 函数参数行为的字符串值

标签 swift

我发现以下代码可以编译并运行:

func foo(p:UnsafePointer<UInt8>) {
    var p = p
    for p; p.memory != 0; p++ {
        print(String(format:"%2X", p.memory))
    }
}

let str:String = "今日"
foo(str)

这会打印出 E4BB8AE697A5这是 今日 的有效 UTF8 表示

据我所知,这是未记录的行为。来自 the document:

When a function is declared as taking a UnsafePointer argument, it can accept any of the following:

  • nil, which is passed as a null pointer
  • An UnsafePointer, UnsafeMutablePointer, or AutoreleasingUnsafeMutablePointer value, which is converted to UnsafePointer if necessary
  • An in-out expression whose operand is an lvalue of type Type, which is passed as the address of the lvalue
  • A [Type] value, which is passed as a pointer to the start of the array, and lifetime-extended for the duration of the call

在这种情况下,str不属于他们。

我错过了什么吗?


已添加:

如果参数类型为UnsafePointer<UInt16>,则无效

func foo(p:UnsafePointer<UInt16>) {
    var p = p
    for p; p.memory != 0; p++ {
        print(String(format:"%4X", p.memory))
    }
}
let str:String = "今日"
foo(str)
//  ^ 'String' is not convertible to 'UnsafePointer<UInt16>'

即使内部String表示为UTF16

let str = "今日"
var p = UnsafePointer<UInt16>(str._core._baseAddress)
for p; p.memory != 0; p++ {
    print(String(format:"%4X", p.memory)) // prints 4ECA65E5 which is UTF16 今日
}

最佳答案

这是有效的,因为自首次发布以来 Swift 团队已经进行了互操作性更改之一 - 你是对的,它看起来还没有进入文档。 StringUnsafePointer<UInt8> 的地方工作是必需的,以便您可以调用期望 const char * 的 C 函数参数而无需很多额外的工作。

看C函数strlen ,在“shims.h”中定义:

size_t strlen(const char *s);

在 Swift 中它是这样实现的:

func strlen(s: UnsafePointer<Int8>) -> UInt

可以用 String 调用没有额外的工作:

let str = "Hi."
strlen(str)
// 3

查看此答案的修订版,了解 C 字符串互操作如何随时间发生变化:https://stackoverflow.com/a/24438698/59541

关于swift - UnsafePointer<UInt8> 函数参数行为的字符串值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27063569/

相关文章:

swift - 如何使用 Publishers.CombineLatest 获得 1 个发布者

ios - 圆角改变 UIView 大小

ios - 将 GestureRecognizer 添加到 UIView 不会触发操作

ios - 如何在 Swift 中使用字符串初始化 NSTextStorage

swift - 无法在 UITextfield 上添加操作以查看 Controller

ios - 如何让Master VC出现在UISplitViewController的右边?

ios - 处理tableView中不会出现的情况(_ :cellForRowAtIndexPath) -> UITableViewCell

ios - 在 .Day 中快速比较两个 NSDate 给出了错误的结果

ios - Swift:子类 MKPolyline

swift - Swift 中字符串插值和字符串初始值设定项之间的区别