Swift 中的 FlatMap 和 Init
FlatMap And Init in Swift
结构
我试图重新创建 Chris Edihoff 在 dotSwift 2016 Demo 中给出的演示中的代码。这是代码。
struct List {
let name:String
let id:Int
}
extension List {
init?(json: [String:AnyObject]) {
guard
let name = json["name"] as? String,
let id = json["id"] as? Int else
{
return nil
}
self.name = name
self.id = id
}
}
let listData = json["data"] as? [[String:AnyObject]]
到目前为止一切似乎都很好。但这就是问题所在。
他做了这样的事情:
let list:[List] = listData.flatMap(List.init)
以上行应该返回列表对象数组。 Chris Edihoff 似乎没有任何问题,但是当我这样做时 Xcode 警告
- flatMap 生成 'U?',而不是预期的上下文结果类型 '_?
这里的List.init
是什么?我从未见过这种初始化对象的方式。它应该是 List()
或者如果我们在这里使用客户初始化,它应该是 List(json:someObject)
对吗?
引用 Chris Edihof 演讲:https://www.youtube.com/watch?v=ewk-XNzXzAA
此代码无法编译的原因有多种。
首先,您不需要下标 json["data"]
- flatMap 的工作就是迭代该数据并初始化列表。
我看到在原始演示文稿中,listData.flatMap
跟在 if let
块之后;这意味着 listData 将被解包而不是 nil。
在您的代码中,您有 let listData = json as? [[String:AnyObject]]
。您的 listData 是 [[String:AnyObject]]?
.
类型的可选类型
所以,解决这个问题的方法是:
if let listData = json as? [[String:AnyObject]] {
let list = listData.flatMap(List.init)
//do something with list
}
此处,listData 的类型正确:[[String: AnyObject]]
。
关于List.init
,它只是一种将初始化程序显式应用于任何 flatMap 提供的方法。您可以用更详细但可能更清晰的方式重写该函数:
listData.flatMap {data in List(json: data)}
结构
我试图重新创建 Chris Edihoff 在 dotSwift 2016 Demo 中给出的演示中的代码。这是代码。
struct List {
let name:String
let id:Int
}
extension List {
init?(json: [String:AnyObject]) {
guard
let name = json["name"] as? String,
let id = json["id"] as? Int else
{
return nil
}
self.name = name
self.id = id
}
}
let listData = json["data"] as? [[String:AnyObject]]
到目前为止一切似乎都很好。但这就是问题所在。 他做了这样的事情:
let list:[List] = listData.flatMap(List.init)
以上行应该返回列表对象数组。 Chris Edihoff 似乎没有任何问题,但是当我这样做时 Xcode 警告
- flatMap 生成 'U?',而不是预期的上下文结果类型 '_?
这里的List.init
是什么?我从未见过这种初始化对象的方式。它应该是 List()
或者如果我们在这里使用客户初始化,它应该是 List(json:someObject)
对吗?
引用 Chris Edihof 演讲:https://www.youtube.com/watch?v=ewk-XNzXzAA
此代码无法编译的原因有多种。
首先,您不需要下标 json["data"]
- flatMap 的工作就是迭代该数据并初始化列表。
我看到在原始演示文稿中,listData.flatMap
跟在 if let
块之后;这意味着 listData 将被解包而不是 nil。
在您的代码中,您有 let listData = json as? [[String:AnyObject]]
。您的 listData 是 [[String:AnyObject]]?
.
类型的可选类型
所以,解决这个问题的方法是:
if let listData = json as? [[String:AnyObject]] {
let list = listData.flatMap(List.init)
//do something with list
}
此处,listData 的类型正确:[[String: AnyObject]]
。
关于List.init
,它只是一种将初始化程序显式应用于任何 flatMap 提供的方法。您可以用更详细但可能更清晰的方式重写该函数:
listData.flatMap {data in List(json: data)}