【问题标题】:How to convert UInt16 to UInt8 in Swift 3?如何在 Swift 3 中将 UInt16 转换为 UInt8?
【发布时间】:2017-11-05 12:56:37
【问题描述】:

我想将 UInt16 转换为 UInt8 数组,但收到以下错误消息:

'init' 不可用:使用'withMemoryRebound(to:capacity:_)' 暂时将内存视为另一种布局兼容的类型。

代码:

    let statusByte: UInt8 = UInt8(status)
    let lenghtByte: UInt16 = UInt16(passwordBytes.count)

    var bigEndian = lenghtByte.bigEndian

    let bytePtr = withUnsafePointer(to: &bigEndian) {
        UnsafeBufferPointer<UInt8>(start: UnsafePointer($0), count: MemoryLayout.size(ofValue: bigEndian))
    }

【问题讨论】:

    标签: swift type-conversion uint16 uint8array


    【解决方案1】:

    如错误消息所示,您必须使用withMemoryRebound() 将指向UInt16 的指针重新解释为指向UInt8 的指针:

    let bytes = withUnsafePointer(to: &bigEndian) {
        $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: bigEndian)) {
            Array(UnsafeBufferPointer(start: $0, count: MemoryLayout.size(ofValue: bigEndian)))
        }
    }
    

    闭包是用指针($0)调用的,这些指针只有效 在闭包的整个生命周期内,不得传递给外部 供以后使用。这就是创建 Array 并将其用作返回值的原因。

    但是有一个更简单的解决方案:

    let bytes = withUnsafeBytes(of: &bigEndian) { Array($0) }
    

    解释: withUnsafeBytes 调用带有UnsafeRawBufferPointer 的闭包到bigEndian 变量的存储中。 因为UnsafeRawBufferPointerUInt8Sequence,所以是一个数组 可以使用 Array($0) 从中创建。

    【讨论】:

      【解决方案2】:

      您可以扩展 Numeric 协议并创建如下数据属性:

      Swift 4 或更高版本

      extension Numeric {
          var data: Data {
              var source = self
              return Data(bytes: &source, count: MemoryLayout<Self>.size)
          }
      }
      

      由于 Swift 3 数据符合 RandomAccessCollection,因此您可以从您的 UInt16 bigEndian 数据创建一个字节数组:

      extension Data {
          var array: [UInt8] { return Array(self) }
      }
      

      let lenghtByte = UInt16(8)
      let bytePtr = lenghtByte.bigEndian.data.array   // [0, 8]
      

      【讨论】:

        猜你喜欢
        • 2022-07-21
        • 1970-01-01
        • 1970-01-01
        • 2017-04-01
        • 2019-10-20
        • 1970-01-01
        • 2023-03-28
        • 2021-06-29
        • 2021-01-22
        相关资源
        最近更新 更多