我有一个结构,该结构具有返回字典表示形式的方法。成员变量是不同类型(字符串和双精度?)的组合
在下面的代码示例中,Xcode将发出警告(表达式从'Double?'隐式强制为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?],则警告消失:
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文档吗?
如果不是,应该是什么?
==编辑==
以下内容也适用:
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
]
}
}
答案 0 :(得分:1)
您可以将frequency
强制转换为Any
,因为后者可以容纳 any 类型。就像将特定Swift类型的实例转换为Objective-C id类型一样。最终,您必须将Any
类型的对象下放到特定的类中,以便能够调用方法和访问属性。
我不建议您使用Any
来构造代码中的数据,或者如果您想指定特定的Any?
(对象可能包含或不包含 some 值时), 。那可能是不良的数据建模的迹象。
Any 可以表示任何类型的实例,包括函数类型。[...]使用 Any 和 AnyObject 仅,当您明确需要它们提供的行为和功能时。 最好始终明确说明您希望在代码中使用的类型。
(重点是我的)
请使用Data
类型。这样您就可以解码Record
或将其编码到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")
答案 1 :(得分:0)
我建议添加Codable
一致性,并让JSONEncoder
完成所有繁重的工作。但是,如果您受制于toDictionary
方法,那么我建议不要使用[String:Any?]
,因为这可能导致不确定的行为(尝试打印字典以获取更多详细信息)。
toDictionary
的可能解决方案是使用元组数组,将其转换为字典:
func toDictionary() -> [String: Any] {
let propsMap: [(String, Any?)] = [
("name", name),
("frequency", frequency)
]
return propsMap.reduce(into: [String:Any]()) { $0[$1.0] = $1.1 }
}
这样,nil属性根本不会在输出字典中接收条目。