[英]Why can we chain flatMap to UserDefaults.standard.data
In an article about UserDefaults in iOS development, I saw a code snippet where flatMap is chained to UserDefaults.standard.data like below:在 iOS 开发中有关 UserDefaults 的文章中,我看到了一个代码片段,其中 flatMap 链接到 UserDefaults.standard.data,如下所示:
self.isReadStatuses = UserDefaults.standard.data(forKey: "isReadStatuses")
.flatMap { try? JSONDecoder().decode([URL: Bool].self, from: $0) } ?? [:]
Does anyone know Why can we use.flatMap here?有谁知道为什么我们可以在这里使用.flatMap?
Because UserDefaults.standard.data(forKey:)
returns Data?
因为UserDefaults.standard.data(forKey:)
返回Data?
- an Optional<Data>
, and Optional
has a .flatMap
method . - 一个Optional<Data>
,并且Optional
有一个.flatMap
方法。
Specifically here, the flatMap
closure gets a non-optional Data
, and attempts to decode it returning another [URL:Bool]?
具体来说, flatMap
闭包获取一个非可选的Data
,并尝试对其进行解码,返回另一个[URL:Bool]?
(also, an optional because of try?
). (另外,由于try?
)。
I can guess why are you confused, although im not sure.我可以猜到你为什么感到困惑,尽管我不确定。 I think you think that .map
(and it's brothers, .flatMap
and .compactMap
) can only be used on Collections (eg an Array).我认为您认为.map
(以及它的兄弟.flatMap
和.compactMap
)只能用于 Collections (例如数组)。 That is completely wrong.那是完全错误的。 .map
(and the other 2) have a meaning of transformation , not iterating through an collection/array. .map
(和其他 2 个)具有转换的含义,而不是遍历集合/数组。 So while they can be used on arrays, they have many more use-cases as well.因此,虽然它们可以在 arrays 上使用,但它们也有更多的用例。
You can read more about differences between those 3 kinds of map
here .您可以在此处阅读有关这 3 种map
之间差异的更多信息。
In the code you showed, the author of that blog post has used .flatMap
with intention of transforming an Optional<Data>
value (aka Data?) to [URL: Bool]
which is the value he wants.在您展示的代码中,该博客文章的作者使用.flatMap
将Optional<Data>
值(又名 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 = [:]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.