swift 字符串(validatingUTF8:)和字符串(utf8String:)之间有区别吗?

vyswwuz2  于 2022-12-26  发布在  Swift
关注(0)|答案(1)|浏览(120)

这两个函数看起来有非常接近的签名和非常接近的描述:

字符串初始化(utf8字符串:)
通过从UTF8编码字节的给定空终止C数组复制数据来创建字符串。

字符串.init(验证UTF8:)
通过复制并验证给定指针引用的以空值结尾的UTF-8数据来创建新字符串。
既然两者都是可空的初始化器,那么它们的实际区别是什么?是否有一个可能的输入会给予每一个不同的输出?如果它们在行为上是相同的,那么推荐使用哪一个?

5sxhfpxr

5sxhfpxr1#

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中实现。

/// 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
    }
  }

并且是基础NSString初始化器的Swift覆盖

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

而后者又在swift-corelibs-foundation/Sources/Foundation/NSString中的非Apple平台上实现。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:)不需要额外的导入。

相关问题