带有混合类型的Swift字典(可选和非可选) [英] Swift dictionary with mix types (optional and non-optional)

查看:111
本文介绍了带有混合类型的Swift字典(可选和非可选)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构,该结构具有返回字典表示形式的方法.成员变量是不同类型(字符串和双精度类型)的组合

I have a struct that has a method to return a dictionary representation. The member variables were a combination of different types (String and Double?)

在下面的代码示例中,Xcode会发出警告(表达式从'Double?'隐式强制为Any)

With the following code example, there would be a warning from Xcode (Expression implicitly coerced from 'Double?' to Any)

struct Record {
  let name: String
  let frequency: Double?

  init(name: String, frequency: Double?) {
    self.name = name
    self.frequency = frequency
  }

  func toDictionary() -> [String: Any] {
    return [
      "name": name,
      "frequency": frequency
    ]
  }
}

但是,如果返回类型[String:Any?],则警告消失:

However if it was returning a type [String: Any?], the warning goes away:

struct Record {
  let name: String
  let frequency: Double?

  init(name: String, frequency: Double?) {
    self.name = name
    self.frequency = frequency
  }

  func toDictionary() -> [String: Any?] {
    return [
      "name": name,
      "frequency": frequency
    ]
  }
}

我的问题是:这是正确的吗?如果是的话,您能指出一些解释这个问题的Swift文档吗?

My question is: Is this correct? And if it is, can you point me to some Swift documentation that explains this?

如果不是,应该是什么?

If it isn't, what should it be?

==编辑==

以下内容也适用:

struct Record {
  let name: String
  let frequency: Double?

  init(name: String, frequency: Double?) {
    self.name = name
    self.frequency = frequency
  }

  func toDictionary() -> [String: Any] {
    return [
      "name": name,
      "frequency": frequency as Any
    ]
  }
}

推荐答案

您可以将frequency强制转换为Any,因为后者可以容纳 any 类型.就像将特定Swift类型的实例转换为Objective-C id类型一样.最终,您必须将类型为Any的对象向下转换为特定的类,才能调用方法和访问属性.

You can cast frequency to Any since the latter can hold any type. It is like casting instances of specific Swift type to the Objective-C id type. Eventually, you'll have to downcast objects of the type Any to a specific class to be able to call methods and access properties.

我不建议您使用Any来构造代码中的数据,或者如果您想特定于Any?(当对象可能具有或不具有 some 值时).那可能是不良的数据建模的迹象.

I would not recommend structuring data in your code using Any, or if you want to be specific Any? (when the object may or may not hold some value). That would be a sign of bad data-modeling.

文档:

Any 可以表示任何类型的实例,包括函数类型.[...]使用 Any AnyObject ,当您明确需要它们提供的行为和功能时. 最好始终明确说明您希望在代码中使用的类型.

Any can represent an instance of any type at all, including function types.[...] Use Any and AnyObject only when you explicitly need the behavior and capabilities they provide. It is always better to be specific about the types you expect to work within your code.

(重点是我的)

相反,请使用Data类型.这样您就可以解码Record或将其编码为Data:

Instead, use the Data type. And you would be able to decode Record or encode it from and into Data:

struct Record : Codable {
    let name: String
    let frequency: Double?

    init(name: String, frequency: Double?) {
        self.name = name
        self.frequency = frequency
    }

    init(data: Data) throws { 
        self = try JSONDecoder().decode(Record.self, from: data) 
    }

    func toData() -> Data {
        guard let data = try? JSONEncoder().encode(self) else {
            fatalError("Could not encode Record into Data")
        }
        return data
    }
}

并像这样使用它:

let record = Record(name: "Hello", frequency: 13.0)
let data = record.toData()

let decodedRecord = try Record(data: data)
print(decodedRecord.name)
print(decodedRecord.frequency ?? "No frequency")

这篇关于带有混合类型的Swift字典(可选和非可选)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆