【问题标题】:Why can we chain flatMap to UserDefaults.standard.data为什么我们可以将 flatMap 链接到 UserDefaults.standard.data
【发布时间】:2021-04-12 12:58:53
【问题描述】:

在一篇关于 iOS 开发中 UserDefaults 的文章中,我看到了一段代码 sn-p,其中 flatMap 链接到 UserDefaults.standard.data,如下所示:

self.isReadStatuses = UserDefaults.standard.data(forKey: "isReadStatuses")
      .flatMap { try? JSONDecoder().decode([URL: Bool].self, from: $0) } ?? [:]

有人知道为什么我们可以在这里使用 .flatMap 吗?

【问题讨论】:

  • flatMap() 可以在Data 实例上使用,不是吗?这就是为什么。关于它转换什么的问题是另一个问题和您可以做的其他测试。
  • @Larme 是 Optional 的 flatMap,而不是 Data

标签: ios swift swiftyuserdefaults


【解决方案1】:

因为UserDefaults.standard.data(forKey:) 返回Data? - 一个Optional<Data>Optional has a .flatMap method

具体来说,flatMap 闭包得到一个非可选的Data,并尝试对其进行解码,返回另一个[URL:Bool]?(也是可选的,因为try?)。

【讨论】:

  • 嗨@New Dev,感谢您的解释并分享有关在可选组件上使用 .flatMap 方法的文档链接。我真的很感激。
【解决方案2】:

我可以猜到你为什么感到困惑,虽然我不确定。我认为您认为.map(以及它的兄弟.flatMap.compactMap)只能用于集合(例如数组)。那是完全错误的。 .map(和其他 2 个)具有 transformation 的含义,而不是遍历集合/数组。因此,虽然它们可以用于数组,但它们也有更多的用例。
您可以阅读更多关于这 3 种 map here 之间差异的信息。
在您展示的代码中,该博客文章的作者使用了.flatMap,意图转换 Optional<Data> 值(又名数据?)到[URL: Bool],这是他想要的值。

let udData = UserDefaults.standard.data(forKey: "isReadStatuses")

// Short way:
let isReadStatuses1 = udData.flatMap {
    try? JSONDecoder().decode([URL: Bool].self, from: $0)
} ?? [:]

// Long way:
let isReadStatuses2: [URL: Bool]
if let data = udData {
    isReadStatuses2 = (try? JSONDecoder().decode([URL: Bool].self, from: data)) ?? [:]
} else {
    isReadStatuses2 = [:]
}

【讨论】:

  • 嗨@Mahdi BM,感谢您的解释。我对在可选数据上使用 flatMap 感到困惑,而且我不知道可选数据具有 flatMap 方法。你的解释确实消除了我的困惑。
  • 基本上,anything 可以有一个map 函数。您也可以创建自己的结构并为其创建 map 函数。但问题是,map 在编程中,即使在其他语言中也意味着 transformation,因此在您希望使您的类型能够很容易变形,而不是在其他地方。
猜你喜欢
  • 2016-02-01
  • 2016-03-18
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多