条件协议一致性:无法将类型 'Array<_>' 的值转换为指定类型“[UInt8]”
Conditional Protocol Conformance: Cannot convert value of type 'Array<_>' to specified type '[UInt8]'
尝试使用条件一致性扩展 Swift 4.1 中的数组、字符串和字典,但在尝试使用 Element
初始化数组时 运行 陷入死胡同通过名为 BinaryCodable
.
的自定义协议符合 Decodable
/Encodable
以下摘录来自 https://github.com/mikeash/BinaryCoder,但已进行调整以使用 Swift 的新条件一致性以使其能够编译。
extension Array: BinaryCodable where Element: BinaryDecodable, Element: BinaryEncodable {
public func binaryEncode(to encoder: BinaryEncoder) throws {
try encoder.encode(self.count)
for element in self {
try element.encode(to: encoder)
}
}
public init(fromBinary decoder: BinaryDecoder) throws {
let binaryElement = Element.self
let count = try decoder.decode(Int.self)
self.init()
self.reserveCapacity(count)
for _ in 0 ..< count {
let decoded = try binaryElement.init(from: decoder)
self.append(decoded)
}
}
}
extension String: BinaryCodable {
public func binaryEncode(to encoder: BinaryEncoder) throws {
try (Array(self.utf8) as! BinaryCodable).binaryEncode(to: encoder)
}
public init(fromBinary decoder: BinaryDecoder) throws {
let utf8: [UInt8] = try Array(fromBinary: decoder)
if let str = String(bytes: utf8, encoding: .utf8) {
self = str
} else {
throw BinaryDecoder.Error.invalidUTF8(utf8)
}
}
}
但是,我得到:
Cannot convert value of type 'Array<_>' to specified type '[UInt8]'
对于这一行:
let utf8: [UInt8] = try Array(fromBinary: decoder)
如有任何帮助,我们将不胜感激。
如果您希望数组的每个元素都有一个值,请将其更改为:
let utf8:Array<UInt8> = try Array(from: decoder);
如果您希望数组的某些元素具有 null 或空值,请将其更改为:
let utf8:Array<UInt8?> = try Array(from: decoder);
为了使 Array<UInt8>
成为 BinaryCodable
,它的元素类型 UInt8
必须是 BinaryCodable
,但事实并非如此。该协议有
其所需方法的默认实现,但一致性必须
仍然明确声明:
extension UInt8: BinaryCodable {}
然后你的extension String
编译,
你甚至可以去掉强制转换 as! BinaryCodable
编码方式(使用guard
可以节省一行):
extension String: BinaryCodable {
public func binaryEncode(to encoder: BinaryEncoder) throws {
try Array(self.utf8).binaryEncode(to: encoder)
}
public init(fromBinary decoder: BinaryDecoder) throws {
let utf8: [UInt8] = try Array(fromBinary: decoder)
guard let str = String(bytes: utf8, encoding: .utf8) else {
throw BinaryDecoder.Error.invalidUTF8(utf8)
}
self = str
}
}
尝试使用条件一致性扩展 Swift 4.1 中的数组、字符串和字典,但在尝试使用 Element
初始化数组时 运行 陷入死胡同通过名为 BinaryCodable
.
Decodable
/Encodable
以下摘录来自 https://github.com/mikeash/BinaryCoder,但已进行调整以使用 Swift 的新条件一致性以使其能够编译。
extension Array: BinaryCodable where Element: BinaryDecodable, Element: BinaryEncodable {
public func binaryEncode(to encoder: BinaryEncoder) throws {
try encoder.encode(self.count)
for element in self {
try element.encode(to: encoder)
}
}
public init(fromBinary decoder: BinaryDecoder) throws {
let binaryElement = Element.self
let count = try decoder.decode(Int.self)
self.init()
self.reserveCapacity(count)
for _ in 0 ..< count {
let decoded = try binaryElement.init(from: decoder)
self.append(decoded)
}
}
}
extension String: BinaryCodable {
public func binaryEncode(to encoder: BinaryEncoder) throws {
try (Array(self.utf8) as! BinaryCodable).binaryEncode(to: encoder)
}
public init(fromBinary decoder: BinaryDecoder) throws {
let utf8: [UInt8] = try Array(fromBinary: decoder)
if let str = String(bytes: utf8, encoding: .utf8) {
self = str
} else {
throw BinaryDecoder.Error.invalidUTF8(utf8)
}
}
}
但是,我得到:
Cannot convert value of type 'Array<_>' to specified type '[UInt8]'
对于这一行:
let utf8: [UInt8] = try Array(fromBinary: decoder)
如有任何帮助,我们将不胜感激。
如果您希望数组的每个元素都有一个值,请将其更改为:
let utf8:Array<UInt8> = try Array(from: decoder);
如果您希望数组的某些元素具有 null 或空值,请将其更改为:
let utf8:Array<UInt8?> = try Array(from: decoder);
为了使 Array<UInt8>
成为 BinaryCodable
,它的元素类型 UInt8
必须是 BinaryCodable
,但事实并非如此。该协议有
其所需方法的默认实现,但一致性必须
仍然明确声明:
extension UInt8: BinaryCodable {}
然后你的extension String
编译,
你甚至可以去掉强制转换 as! BinaryCodable
编码方式(使用guard
可以节省一行):
extension String: BinaryCodable {
public func binaryEncode(to encoder: BinaryEncoder) throws {
try Array(self.utf8).binaryEncode(to: encoder)
}
public init(fromBinary decoder: BinaryDecoder) throws {
let utf8: [UInt8] = try Array(fromBinary: decoder)
guard let str = String(bytes: utf8, encoding: .utf8) else {
throw BinaryDecoder.Error.invalidUTF8(utf8)
}
self = str
}
}