为什么我们可以将 flatMap 链接到 UserDefaults.standard.data
Why can we chain flatMap to UserDefaults.standard.data
在一篇关于 iOS 开发中的 UserDefaults 的文章中,我看到了一个代码片段,其中 flatMap 被链接到 UserDefaults.standard.data,如下所示:
self.isReadStatuses = UserDefaults.standard.data(forKey: "isReadStatuses")
.flatMap { try? JSONDecoder().decode([URL: Bool].self, from: [=11=]) } ?? [:]
有谁知道为什么我们可以在这里使用.flatMap?
因为 UserDefaults.standard.data(forKey:)
returns Data?
- 一个 Optional<Data>
,并且 Optional
has a .flatMap
method.
特别是这里,flatMap
闭包得到一个非可选的 Data
,并尝试解码它返回另一个 [URL:Bool]?
(也是可选的,因为 try?
).
我能猜到你为什么感到困惑,虽然我不确定。我想你认为 .map
(和它的兄弟,.flatMap
和 .compactMap
)只能用于集合(例如数组)。那是完全错误的。 .map
(和其他 2 个)具有 转换 的含义,而不是迭代 collection/array。因此,虽然它们可以用于数组,但它们也有更多的用例。
您可以阅读更多关于这 3 种 map
here.
之间差异的信息
在您展示的代码中,该博客 post 的作者使用 .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: [=10=])
} ?? [:]
// Long way:
let isReadStatuses2: [URL: Bool]
if let data = udData {
isReadStatuses2 = (try? JSONDecoder().decode([URL: Bool].self, from: data)) ?? [:]
} else {
isReadStatuses2 = [:]
}
在一篇关于 iOS 开发中的 UserDefaults 的文章中,我看到了一个代码片段,其中 flatMap 被链接到 UserDefaults.standard.data,如下所示:
self.isReadStatuses = UserDefaults.standard.data(forKey: "isReadStatuses")
.flatMap { try? JSONDecoder().decode([URL: Bool].self, from: [=11=]) } ?? [:]
有谁知道为什么我们可以在这里使用.flatMap?
因为 UserDefaults.standard.data(forKey:)
returns Data?
- 一个 Optional<Data>
,并且 Optional
has a .flatMap
method.
特别是这里,flatMap
闭包得到一个非可选的 Data
,并尝试解码它返回另一个 [URL:Bool]?
(也是可选的,因为 try?
).
我能猜到你为什么感到困惑,虽然我不确定。我想你认为 .map
(和它的兄弟,.flatMap
和 .compactMap
)只能用于集合(例如数组)。那是完全错误的。 .map
(和其他 2 个)具有 转换 的含义,而不是迭代 collection/array。因此,虽然它们可以用于数组,但它们也有更多的用例。
您可以阅读更多关于这 3 种 map
here.
之间差异的信息
在您展示的代码中,该博客 post 的作者使用 .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: [=10=])
} ?? [:]
// Long way:
let isReadStatuses2: [URL: Bool]
if let data = udData {
isReadStatuses2 = (try? JSONDecoder().decode([URL: Bool].self, from: data)) ?? [:]
} else {
isReadStatuses2 = [:]
}