gpt4 book ai didi

swift - CodingKeys 一致性会产生编译器错误

转载 作者:行者123 更新时间:2023-11-30 10:47:40 25 4
gpt4 key购买 nike

我有一个符合 CodingKey 的结构 DynamicKey 。然后我决定使用编码 [String: Any] 的函数来扩展 KeyedEncodingContainer 现有的功能..

现在我到达了 Struct Foo 中的一致性部分,但出现了编译器错误..

当编译器继承自具有一致性的 DynamicKey 时,编译器会说 Foo.CodingKeys 不符合 CodingKeys 的任何想法吗?

不工作的代码:

struct DynamicKey: CodingKey, Equatable, ExpressibleByStringLiteral {
var stringValue: String
var intValue: Int? { return nil }

init?(stringValue: String) {
self.stringValue = stringValue
}

init?(intValue: Int) {
return nil
}

//MARK:- Equatable Methods
public static func == (lhs: DynamicKey, rhs: DynamicKey) -> Bool {
return lhs.stringValue == rhs.stringValue
}

//MARK:- ExpressibleByStringLiteral Methods
public init(stringLiteral value: String) {
self.stringValue = value
}

public init(unicodeScalarLiteral value: String) {
self.init(stringLiteral: value)
}

public init(extendedGraphemeClusterLiteral value: String) {
self.init(stringLiteral: value)
}
}

extension KeyedEncodingContainer where Key: CodingKey /*where Key == DynamicKey*/ {
mutating func encodeDynamicValues(_ value: [String: Any], forKey key: Key) throws {
//Other code here..
}
}

struct Foo: Encodable {
var arr: [String: Any]

public func encode(to encoder: Encoder) throws {

//Compiler Error: Instance method 'container(keyedBy:)' requires that 'Foo.CodingKeys' conform to 'CodingKey'
//However, Foo.CodingKeys conforms to `CodingKey` because `DynamicKey` implements the protocol..
var container = encoder.container(keyedBy: CodingKeys.self)



try container.encodeDynamicValues(arr, forKey: .arr)
}

enum CodingKeys: DynamicKey {
case arr
}
}

但是,如果我将 DynamicKey 更改为类,然后使用 & 运算符使枚举符合要求,编译器错误就会消失(没有 & ,它会给出同样的错误)..为什么?

工作代码:

final class DynamicKey: CodingKey { //I don't need the equatable and expressible when it's a class so ignore that part.. adding it doesn't change anything..
var stringValue: String
var intValue: Int? { return nil }

init?(stringValue: String) {
self.stringValue = stringValue
}

init?(intValue: Int) {
return nil
}
}

extension KeyedEncodingContainer where Key: CodingKey /*where Key == DynamicKey*/ {
mutating func encodeDynamicValues(_ value: Any, forKey key: Key) throws {
//Other Code Here..
}
}

struct Foo: Encodable {
var arr: [String: Any]

public func encode(to encoder: Encoder) throws {
//CodingKeys now conforms to `CodingKey` because I made `DynamicKey` a class and used the `&` `CodingKey`
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeDynamicValues(arr, forKey: .arr)
}

enum CodingKeys: DynamicKey & CodingKey {
case arr
}
}

最佳答案

你的第一个例子

第一个示例中的问题只是您对这一行的理解问题:

enum CodingKeys: DynamicKey

你说:

Any ideas why the compiler says that Foo.CodingKeys does not conform to CodingKeys when it inherits from DynamicKey which has the conformance?

但是 Foo.CodingKeys “继承自 DynamicKey”。没有什么可以从结构“继承”。这里的符号与继承无关。您所做的是一个具有 DynamicKey 类型的原始值的枚举。 (通常你无法做到这一点 - 原始值类型需要“可由字符串、整数或浮点文字表达”,但你可以通过将 DynamicKey Equatable 和 ExpressibleByStringLiteral 来解决这个问题。)

这与您所说的语法相同:

enum MyEnum : Int {
case myCase // zero
}

(您还因为对枚举使用神奇的名称 CodingKeys 而感到困惑。但这可能没有直接关系。)

<小时/>

你的第二个例子

然后在第二个示例中,DynamicKey 是一个类,您会以完全相反的方式感到困惑。在这里,你做了一些完全不同的事情:

enum CodingKeys: DynamicKey & CodingKey {

在这里,您的枚举有任何原始值类型;冒号后面的内容声明协议(protocol)限制。但在这里你又用另一种方式欺骗了自己,因为事实上 DynamicKey 部分是无关紧要的;如果您简单地说,代码也可以编译

enum CodingKeys: CodingKey {

该示例中真正发生的事情是,您要求自动合成与 CodingKey 的一致性,并且您已经得到了它。

关于swift - CodingKeys 一致性会产生编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55420192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com