下面函数“parseB”中用于 flatMap 的语法使用圆括号,而不是大括号。
struct Episode {
let id: String
let title: String
}
extension Episode {
init?(dictionary: [String: AnyObject]) {
guard let id = dictionary["id"] as? String, title = dictionary["title"] as? String else { return nil }
self.id = id
self.title = title
}
}
func parseA(dictionaries: [[String: AnyObject]]) -> [Episode] {
return dictionaries.flatMap { dic in Episode.init(dictionary: dic)}
}
func parseB(dictionaries: [[String: AnyObject]]) -> [Episode] {
return dictionaries.flatMap (Episode.init)
}
有一个平面 map 的实现,看起来是这样的
public func flatMap<U>(@noescape f: (Wrapped) throws -> U!) rethrows -> U!
读到这里我还是不明白,在上面的例子中,Episode 上的 init 怎么没有括号。
有时 Swift 非常擅长推断事物,以至于很难理解正在发生的事情。有人可以帮我理解为什么 Episodes 的初始化方法不使用括号吗?
...flatMap (Episode.init)
引用 1:https://talk.objc.io/episodes/S01E01-networking 引用 2:https://github.com/objcio/S01E01-networking
最佳答案
让我们从一个简单的代码片段开始
[1,2,3].map(String.init) // ["1", "2", "3"]
此处 map
遍历数组 [1,2,3] 的每个元素,每次都将第 n 个元素传递给 String
初始化程序。
这是可行的,因为
- 数组以
Int
作为通用元素 String
有一个 init 接受Int
作为唯一参数
为什么 ( ... )
而不是 { ... }
?
在这种情况下,我们使用 .map(...)
而不是 .map{ ... }
因为我们要传递给 map
一个在别处定义的函数(以及一个初始化器),我们没有直接编写函数/闭包。
就像我们写作的时候
func isEven(n:Int) -> Bool {
return n % 2 == 0
}
[1,2,3].filter(isEven) // [2]
这里我们传递过滤上面定义的函数,所以我们使用()
。
当然我们也可以直接用{ ... }
来写函数
[1,2,3].filter { (n:Int) -> Bool in
return n % 2 == 0
}
你的代码
在你的代码中这有效
dictionaries.flatMap (Episode.init)
因为 Episode
有一个 init
接受 dictionaries
中相同类型的元素。
事实上 dictionaries
的每个元素都有这种类型 [String: AnyObject]
并且 Episode 的初始化接受相同的类型。
init?(dictionary: [String: AnyObject]) { ... }
关于ios - 了解 Swift 平面 map 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38995983/