【问题标题】:FlatMap And Init in SwiftSwift 中的 FlatMap 和 Init
【发布时间】:2016-09-02 21:48:11
【问题描述】:

结构

我尝试重新创建 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

【问题讨论】:

    标签: ios swift functional-programming flatmap


    【解决方案1】:

    这段代码无法编译的原因有很多。 首先,您无需下标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)}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-23
      • 2017-05-15
      • 2021-05-03
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      相关资源
      最近更新 更多