Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 在超类中实现CodingKey映射_Swift_Struct_Swift Protocols - Fatal编程技术网

Swift 在超类中实现CodingKey映射

Swift 在超类中实现CodingKey映射,swift,struct,swift-protocols,Swift,Struct,Swift Protocols,我有一个结构,它有一些属性,一个CodingKey枚举(为了符合Codable协议)和一些计算变量,这些变量返回一个映射到字符串的键数组 我试图做的是将这些计算变量提取到协议(如果我必须将结构更改为类,则为超类),以避免在每个结构/类中重复实现。而且我需要很多 问题是我找不到了解CodingKey枚举的方法 编辑: DBentity /// Basic protocol for any object directly related with a database table. public p

我有一个结构,它有一些属性,一个CodingKey枚举(为了符合Codable协议)和一些计算变量,这些变量返回一个映射到字符串的键数组

我试图做的是将这些计算变量提取到协议(如果我必须将结构更改为类,则为超类),以避免在每个结构/类中重复实现。而且我需要很多

问题是我找不到了解CodingKey枚举的方法

编辑: DBentity

/// Basic protocol for any object directly related with a database table.
public protocol DBEntity: Codable, Equatable {}
守则:

///////////////////////////////////////////////////////////////////////

// MARK: - Entity Properties

struct AccountsAddresses: DBEntity {

    let statusMobile: String?
    let codeAccount: Int?
    let codeUnitOrg: String?
    let codeSalesOrg: String?
    let codeAddress: Int?
    let codeType: String?
    let byDefault: String?
    let transfered: String?
}

///////////////////////////////////////////////////////////////////////

// MARK: - Table Columns

extension AccountsAddresses {

    /// Table name.
    static var tableName = "ACCOUNTS_ADDRESSES"

    /// Table columns keys.
    enum CodingKeys: String, CodingKey, CaseIterable {
        case statusMobile   = "status_mobile"
        case codeAccount    = "code_account"
        case codeUnitOrg    = "code_unit_org"
        case codeSalesOrg   = "code_sales_org"
        case codeAddress    = "code_address"
        case codeType       = "code_type"
        case byDefault      = "by_default"
        case transfered
    }

/* This is what I'm trying to extract to a protocol(extension) or super-class. */

    /// All table columns keys.
    static var columns: [String] = CodingKeys.allCases.map { $0.rawValue }
    static var columnsJoined: String = columns.joined(separator: String.commaSpace)
    static var columnsTableName: [String] = columns.map { tableName + String.dot + $0 }
    static var columnsJoinedTableName: String = columnsTableName.joined(separator: String.commaSpace)
}
编辑

使用Sweeper答案中的给定代码,我试图在新结构中实现协议,但编译器要求将类型设置为typealias CodingKeyType(因为定义的协议具有associatedtype)

下面是要测试的结构:

struct AccountsTest: Table {

    typealias CodingKeyType = <#type#>
}
编译器继续显示错误,我找不到实现这一点的方法

'CaseIterable' requires the types 'Keys' and 'String.Element' (aka 'Character') be equivalent
完成这件事有什么建议吗


谢谢

请注意,您试图提取的属性不是计算属性

要提取的属性似乎只依赖于
tableName
CodingKeys
,因此我们可以编写如下协议:

protocol SomeProtocol {
    associatedtype CodingKeyType : (CodingKey & CaseIterable & RawRepresentable)
    static var tableName: String { get }
}
然后是这样的扩展(我已将属性转换为计算属性):


请注意,您尝试提取的属性不是计算属性

要提取的属性似乎只依赖于
tableName
CodingKeys
,因此我们可以编写如下协议:

protocol SomeProtocol {
    associatedtype CodingKeyType : (CodingKey & CaseIterable & RawRepresentable)
    static var tableName: String { get }
}
然后是这样的扩展(我已将属性转换为计算属性):


你不需要自己做转换。您可以使用
decoder.keyDecodingStrategy=.convertFromSnakeCase
,您的json将映射到您的camel-case属性

有关更多信息:


您不需要自己进行转换。您可以使用
decoder.keyDecodingStrategy=.convertFromSnakeCase
,您的json将映射到您的camel-case属性

有关更多信息:


那么什么是DBEntity?@matt(后期编辑)DBEntity是与数据库表直接相关的任何对象的协议。那么什么是DBEntity?@matt(后期编辑)DBEntity是与数据库表直接相关的任何对象的协议。你完全正确,我的计算属性错了(多大的错误)。非常感谢你的回答!这正是我要找的!你太棒了!我已经编辑了原始帖子,添加了显示错误的新代码。我找不到要设置为typealias CodingKeyType的类型…@JavierFernandezMartínez您应该将
CodingKeys
Enum作为typealias。不需要创建新类型。我已经尝试过:typealias ColumnKeysType=CodingKeys,但编译器继续显示错误。我现在的错误是,我意外地从CodingKeys枚举中删除了protocols CodingKey,caseitrable。现在一切正常。再次感谢你!你完全正确,我对计算属性的看法是错误的(多大的错误)。非常感谢你的回答!这正是我要找的!你太棒了!我已经编辑了原始帖子,添加了显示错误的新代码。我找不到要设置为typealias CodingKeyType的类型…@JavierFernandezMartínez您应该将
CodingKeys
Enum作为typealias。不需要创建新类型。我已经尝试过:typealias ColumnKeysType=CodingKeys,但编译器继续显示错误。我现在的错误是,我意外地从CodingKeys枚举中删除了protocols CodingKey,caseitrable。现在一切正常。再次感谢你!谢谢你的回答!我曾尝试过使用KeyDecoding策略,但(不幸的是)有些键不符合完全蛇壳命名。谢谢你的回答!我曾尝试过使用KeyDecoding策略,但(不幸的是)有些键并不完全符合snakecase命名。
protocol SomeProtocol {
    associatedtype CodingKeyType : (CodingKey & CaseIterable & RawRepresentable)
    static var tableName: String { get }
}
extension SomeProtocol where CodingKeyType.RawValue == String {
    static var columns: [String] { return CodingKeyType.allCases.map { $0.rawValue } }
    static var columnsJoined: String { return columns.joined(separator: " ") }
    static var columnsTableName: [String] { return columns.map { tableName + "." + $0 } }
    static var columnsJoinedTableName: String { return columnsTableName.joined(separator: " ") }
}