这两个函数似乎有非常接近的签名和非常接近的描述:

String.init(utf8String:)
Creates a string by copying the data from a given null-terminated C array of UTF8-encoded bytes.

String.init(validatingUTF8:)
Creates a new string by copying and validating the null-terminated UTF-8 data referenced by the given pointer.

由于两者都是可以为空的初始值设定项,它们的实际区别是什么?是否存在一个可能的输入, for each 输入提供不同的输出?如果它们在行为上相同,那么推荐使用哪一个?

推荐答案

String.init(validatingUTF8:)是一种来自SWIFT标准库的方法,实现在CString.swift:

  public init?(validatingUTF8 cString: UnsafePointer<CChar>) {
    let len = UTF8._nullCodeUnitOffset(in: cString)
    guard let str = cString.withMemoryRebound(to: UInt8.self, capacity: len, {
      String._tryFromUTF8(UnsafeBufferPointer(start: $0, count: len))
    })
    else { return nil }

    self = str
  }

String.init(utf8String:)NSStringAPI.swift:

  /// Creates a string by copying the data from a given
  /// C array of UTF8-encoded bytes.
  public init?(utf8String bytes: UnsafePointer<CChar>) {
    if let str = String(validatingUTF8: bytes) {
      self = str
      return
    }
    if let ns = NSString(utf8String: bytes) {
      self = String._unconditionallyBridgeFromObjectiveC(ns)
    } else {
      return nil
    }
  }

是Foundation NSString初始化式的SWIFT覆盖

- (nullable instancetype)initWithUTF8String:(const char *)nullTerminatedCString

它又在swift-corelibs-foundation/Sources/Foundation/NSString.swift个版本中实现了非苹果平台

public convenience init?(utf8String nullTerminatedCString: UnsafePointer<Int8>) {
    guard let str = String(validatingUTF8: nullTerminatedCString) else { return nil }
    self.init(str)
}

因此,这两种方法在转换C字符串的方式上没有区别,但是String.init(utf8String:)需要import Foundation,而String.init(validatingUTF8:)不需要额外的导入.

Swift相关问答推荐

是否可以将字典项绑定到文本字段?

数据不会被ARC删除在swift'

如何在向照片添加文本时定义文本对齐、文本背景的Alpha和在文本之前添加图像

如何将函数参数(字符串文字)标记为可本地化?

文件命名&NumberForMatter+扩展名&:含义?

在Swift中如何用变量计算0.9的立方

根据其属性组合 2 个模型以在 Swift 中创建另一个模型

如何在 macOS/AppKit 的窗口选项卡上接受拖动项目的放置?

从文字创建数组时的 Swift 宏

MainActor 隔离可变存储属性为何会出现可发送错误?

Swift - 订阅视图之外的绑定值

如何获得不同的插入和移除过渡动画?

阻止其他类型的键盘

AVPlayer 在 iOS 15.4 中寻求 completionHandler 返回 false

无法从自定义动态框架(Swift)访问类

如何从 Swift 中的字符串生成条形码?

更改日期 Select 器的文本 colored颜色

在 Swift 中将计时器标签格式化为小时:分钟:秒

如何在 Swift 中遍历 struct 属性?

Swift 3:小数到 Int