【问题标题】:Using a template type in a swift protocol definition在 swift 协议定义中使用模板类型
【发布时间】:2017-04-07 06:34:39
【问题描述】:

如何在 swift 中声明一个函数参数类型取决于采用该协议的类型的协议?

有点像

 protocol EndianConvertible<T> {
       init( litteEndian: T );
       func litteEndian() -> T;
 }

背景: 我正在尝试快速为小端二进制流编写流解码器。

其中一部分是通用函数

class ReadStream {

 var offset : Int = 0;
 var data : Data;

 func readIntLE<T : Integer>() -> T {
    var d : T = 0
    let intBits = data.withUnsafeBytes({(bytePointer: UnsafePointer<UInt8>) -> T in
        bytePointer.advanced(by: offset).withMemoryRebound(to: T.self, capacity: MemoryLayout<T>.size) { pointer in
            offset += MemoryLayout<T>.size
            return pointer.pointee
        }
    })
    d = T(littleEndian: intBits)
  }
} 

由于 Integer 协议未指定 init(litteEndian: T) 可用而无法编译,并且修复它的明显方法似乎有一个添加该规范的协议。

【问题讨论】:

  • 协议不允许泛型参数,因此对于上面的第一个 sn-p,您可以在协议中使用关联类型 (protocol Foo { associatedtype T; init(litteEndian: T); /* ... */ })。

标签: generics swift3 protocols


【解决方案1】:

您可以在协议中使用 Self 来引用实现它的类/类型的具体类型:

protocol EndianConvertible
{
       init( litteEndian: Self );
       func litteEndian() -> Self;
}

【讨论】:

  • 完美,参考自我作品。现在我遇到了下一个问题: func readUInt32() -> UInt32 { return readIntLE() } 只有上面的定义我得到一个错误'无法推断通用参数 T'扩展 UInt32:EndianConvertible { } 导致'类型UInt32 不符合 EndianConvertible'
猜你喜欢
  • 1970-01-01
  • 2015-11-18
  • 1970-01-01
  • 2018-11-27
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
相关资源
最近更新 更多