swift – flatMap API契约如何转换可选输入到非可选结果?
这是Swift 3.0.2中flatMap的契约
public struct Array<Element> : RandomAccessCollection,MutableCollection { public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] } 如果我取一个[String?]数组,则flatMap返回[String] let albums = ["Fearless",nil,"Speak Now","Red"] let result = albums.flatMap { $0 } type(of: result) // Array<String>.Type 这里ElementOfResult变成String,为什么不是String? ?泛型类型系统如何从表达式中删除Optional部分?
当您使用身份转换{$0}时,编译器会推断出ElementOfResult? (转换的结果)等效于Element(转换的参数).在这种情况下,Element是String?,因此ElementOfResult? ==字符串?这里不需要可选的促销,因此可以推断ElementOfResult是String.
因此,在这种情况下flatMap(_ :)返回[String]. 在内部,这个转换是从闭包返回的ElementOfResult?通过有条件地展开可选项来完成ElementOfResult,如果成功,则将未展开的值附加到结果中.你可以看到exact implementation here. 作为附录,请注意as Martin points out,闭包只有在单语句闭包时才会参与类型推断(见this related bug report).其原因是Jordan Rose in this mailing list discussion:
这意味着对于具有多个语句的闭包,这些语句传递给map(_ :)或flatMap(_ :)(其中结果类型是通用占位符)等方法,您必须显式地注释闭包的返回类型,或方法返回自己. 例如,这不编译: // error: Unable to infer complex closure return type; add explicit type to disambiguate. let result = albums.flatMap { print($0 as Any) return $0 } 但这些做到: // explicitly annotate [ElementOfResult] to be [String] – thus ElementOfResult == String. let result: [String] = albums.flatMap { print($0 as Any) return $0 } // explicitly annotate ElementOfResult? to be String? – thus ElementOfResult == String. let result = albums.flatMap { element -> String? in print(element as Any) return element } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |