Swift 4:结构中的结构

Swift 4:结构中的结构,swift,swift4,codable,Swift,Swift4,Codable,我在创建结构时遇到问题 我的结构: public struct Device: Codable { let data: DeviceData let meta: Meta? } public struct DeviceData: Codable { let deviceID: String? let type: String? let attributes: Attributes? private enum CodingKeys: String

我在创建结构时遇到问题

我的结构:

public struct Device: Codable {
    let data: DeviceData
    let meta: Meta?
}

public struct DeviceData: Codable {
    let deviceID: String?
    let type: String?
    let attributes: Attributes?

    private enum CodingKeys: String, CodingKey {
        case deviceID = "id"
        case type
        case attributes
    }
}

public struct Attributes: Codable {
    let name: String?
    let asdf: String?
    let payload: Payload?
}

public struct Payload: Codable {
    let example: String?
}

public struct Meta: Codable {
    let currentPage: Int?
    let nextPage: Int?
    let deviceID: [String]?
}
当我现在要创建此结构的元素时,使用:

var exampleData = Device(
        data: DeviceData(
            type: "messages",
            attributes: Attributes(
                name: "Hello World",
                asdf: "This is my message",
                payload: Payload(
                    example: "World"
                )
            )
        ),
        meta: Meta(
            deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
        )
    )
我会得到一个错误。无法详细指定此错误,因为当我删除“meta”元素时,由于它是可选的,会发生另一个错误。。。此特定代码的错误消息为:

调用中的额外参数“meta”


我希望有人能帮助我。

您忘记了调用
DeviceData.init(deviceID:type:attributes:)
deviceID:
命名参数,您还忘记了
currentPage
nextPage
Meta.init(currentPage:nextPage:deviceID)
的命名参数

下面是一个编译的示例:

var exampleData = Device(
    data: DeviceData(
        deviceID: "someID",
        type: "messages",
        attributes: Attributes(
            name: "Hello World",
            asdf: "This is my message",
            payload: Payload(
                example: "World"
            )
        )
    ),
    meta: Meta(
        currentPage: 123,
        nextPage: 456,
        deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
    )
)

您忘记了调用
DeviceData.init(deviceID:type:attributes:)
deviceID:
命名参数,还忘记了
currentPage
nextPage
Meta.init(currentPage:nextPage:deviceID)
命名参数

下面是一个编译的示例:

var exampleData = Device(
    data: DeviceData(
        deviceID: "someID",
        type: "messages",
        attributes: Attributes(
            name: "Hello World",
            asdf: "This is my message",
            payload: Payload(
                example: "World"
            )
        )
    ),
    meta: Meta(
        currentPage: 123,
        nextPage: 456,
        deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
    )
)

您省略了
DeviceData
Meta
初始值设定项的参数。在对另一个答案的评论中,您会问:


我是否必须添加它们并将它们设置为nil,即使它们是可选的?也许这是我的问题

您可以这样做,例如:

meta: Meta(currentPage: nil,
           nextPage: nil,
           deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
          )
init(currentPage : Int? = nil, nextPage : Int? = nil, deviceID : [String]? = nil)
{
   self.currentPage = currentPage
   self.nextPage = nextPage
   self.deviceID = deviceID
}
或者,您可以编写自己的初始值设定项,而不是依赖默认的memberwise初始值设定项,并在那里提供默认值,而不是每次调用,例如:

meta: Meta(currentPage: nil,
           nextPage: nil,
           deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
          )
init(currentPage : Int? = nil, nextPage : Int? = nil, deviceID : [String]? = nil)
{
   self.currentPage = currentPage
   self.nextPage = nextPage
   self.deviceID = deviceID
}
您的原始调用(省略了当前页面和下一页)将是有效的,并将这两个设置为
nil


HTH

您省略了
DeviceData
Meta
初始值设定项的参数。在对另一个答案的评论中,您会问:


我是否必须添加它们并将它们设置为nil,即使它们是可选的?也许这是我的问题

您可以这样做,例如:

meta: Meta(currentPage: nil,
           nextPage: nil,
           deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
          )
init(currentPage : Int? = nil, nextPage : Int? = nil, deviceID : [String]? = nil)
{
   self.currentPage = currentPage
   self.nextPage = nextPage
   self.deviceID = deviceID
}
或者,您可以编写自己的初始值设定项,而不是依赖默认的memberwise初始值设定项,并在那里提供默认值,而不是每次调用,例如:

meta: Meta(currentPage: nil,
           nextPage: nil,
           deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
          )
init(currentPage : Int? = nil, nextPage : Int? = nil, deviceID : [String]? = nil)
{
   self.currentPage = currentPage
   self.nextPage = nextPage
   self.deviceID = deviceID
}
您的原始调用(省略了当前页面和下一页)将是有效的,并将这两个设置为
nil


HTH

这里有很多可选性,这会使数据模型比必要的更难使用。您确定
设备(数据:DeviceData(设备ID:nil,类型:nil,属性:nil),meta:meta(当前页面:nil,下一页:nil,属性:nil))成为您的模型支持的值有意义吗?
您完全正确。。。将继续改进此代码,这只是为了理解:)谢谢!这里有很多可选性,这会使数据模型比必要的更难使用。您确定
设备(数据:DeviceData(设备ID:nil,类型:nil,属性:nil),meta:meta(当前页面:nil,下一页:nil,属性:nil))成为您的模型支持的值有意义吗?
您完全正确。。。将继续改进此代码,这只是为了理解:)谢谢!我是否必须添加它们并将它们设置为nil,即使它们是可选的?也许这是我的问题@rocklyve是的,只有1个合成初始值设定项,它包含所有未初始化的存储属性。如果语言允许从初始值设定项调用中省略
nil
字段,编译器将需要生成
2^numOptionalFields
不同的初始值设定项,这些初始值设定项的分解非常快(1、2、4、8、16、32,…)。这可能会给重载解析带来麻烦,但可能值得研究。我是否必须添加它们并将它们设置为nil,即使它们是可选的?也许这是我的问题@rocklyve是的,只有1个合成初始值设定项,它包含所有未初始化的存储属性。如果语言允许从初始值设定项调用中省略
nil
字段,编译器将需要生成
2^numOptionalFields
不同的初始值设定项,这些初始值设定项的分解非常快(1、2、4、8、16、32,…)。这可能会给过载解决带来麻烦,但可能值得调查。