的字符串值函数参数行为

的字符串值函数参数行为

本文介绍了UnsafePointer<UInt8> 的字符串值函数参数行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I found the following code compiles and works:

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,这是 今日

据我所知,这是未记录的行为.来自 文档:

As far as I know, this is undocumented behavior. from the document:

当函数被声明为采用 UnsafePointer 参数时,它可以接受以下任何一种:

  • nil,作为空指针传递
  • UnsafePointer、UnsafeMutablePointer 或 AutoreleasingUnsafeMutablePointer 值,必要时转换为 UnsafePointer
  • 一个输入输出表达式,其操作数是 Type 类型的左值,作为左值的地址传递
  • 一个 [Type] 值,作为指向数组开头的指针传递,并在调用期间延长生命周期

在这种情况下,str 不属于它们.

In this case, str is non of them.

我错过了什么吗?

添加:

如果参数类型为UnsafePointer

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

Even though the internal String representation is 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 团队自首次发布以来所做的互操作性更改之一 - 你是对的,它看起来好像没有做它进入文档呢.String 适用于需要 UnsafePointer 的地方,这样您就可以调用需要 const char * 参数的 C 函数,而无需太多额外的工作.

This is working because of one of the interoperability changes the Swift team has made since the initial launch - you're right that it looks like it hasn't made it into the documentation yet. String works where an UnsafePointer<UInt8> is required so that you can call C functions that expect a const char * parameter without a lot of extra work.

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

Look at the C function strlen, defined in "shims.h":

size_t strlen(const char *s);

在 Swift 中是这样的:

In Swift it comes through as this:

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

可以用 String 调用而无需额外工作:

Which can be called with a String with no additional work:

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

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

Look at the revisions on this answer to see how C-string interop has changed over time: https://stackoverflow.com/a/24438698/59541

这篇关于UnsafePointer&lt;UInt8&gt; 的字符串值函数参数行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 23:43