从 UnsafeBufferPointer 到 UnsafeRawBufferPointer 的隐式转换

Implicit conversion from UnsafeBufferPointer to UnsafeRawBufferPointer

UnsafePointer can be implicitly castUnsafeRawPointers 当作为参数传递时:

var x = 42

func print<T>(address p: UnsafeRawPointer, as type: T.Type) {
    print(p.load(as: type))
}

withUnsafePointer(to: &x) { (ptr) in
    print(address: ptr, as: Int.self)  // Prints "42"
}

但是,UnsafeBufferPointer 似乎无法隐式转换为 UnsafeRawBufferPointer

var x = 42

func printBuffer<T>(address p: UnsafeRawBufferPointer, as type: T.Type) {
    print(p.load(as: type))
}

withUnsafePointer(to: &x) { (ptr) in
    let buff = UnsafeBufferPointer(start: ptr, count: 1)
    printBuffer(address: buff, as: Int.self)  // 1
}

在此代码段中,标记为 // 1 错误的行:

cannot convert value of type 'UnsafeBufferPointer' to expected argument type 'UnsafeRawBufferPointer'

为什么这个隐式转换是不可能的,而前一个是允许的?

您不能一个UnsafeBufferPointer转换为UnsafeRawBufferPointer 因为这不仅仅是重新解释指针:它需要 计算原始字节数。

但是您可以从 UnsafeBufferPointer:

创建 UnsafeRawBufferPointer
withUnsafePointer(to: &x) { (ptr) in
    let buff = UnsafeBufferPointer(start: ptr, count: 1)
    let rawBuff = UnsafeRawBufferPointer.init(buff)
    printBuffer(address: rawBuff, as: Int.self)
}

下面是 UnsafeRawBufferPointer.swift.gyb 中初始化器的实现:

  /// Creates a raw buffer over the contiguous bytes in the given typed buffer.
  ///
  /// - Parameter buffer: The typed buffer to convert to a raw buffer. The
  ///   buffer's type `T` must be a trivial type.
  @_inlineable
  public init<T>(_ buffer: UnsafeMutableBufferPointer<T>) {
    self.init(start: buffer.baseAddress!,
      count: buffer.count * MemoryLayout<T>.stride)
  }