阅读背景:

为什么通过扩展使用的flatMap返回的结果与直接调用的结果不同?

来源:互联网 

Consider this code...

考虑这段代码…

import Foundation

let source = ["A", "B", nil, "D"]
print(type(of:source))

let result1 = source.flatMap{ 

Consider this code...

考虑这段代码…

import Foundation

let source = ["A", "B", nil, "D"]
print(type(of:source))

let result1 = source.flatMap{ $0 }
print(type(of:result1))
print(result1)

extension Array
{
    func sameThing() -> Array
    {
        return self.flatMap{ $0 }
    }
}

let result2 = source.sameThing()
print(type(of:result2))
print(result2)

result1 is an Array<String> while result2 is an Array<Optional<String>>. But why?

resulis数组 <可选的 >。但是为什么呢?

I've tried using a Sequence instead of an array, but no luck there either.

我尝试过使用序列而不是数组,但也没有运气。

1 个解决方案

#1


1  

Your return type preserves generic type

返回类型保留泛型类型

func sameThing(separator:String = " ") -> Array

Therefore on optional elements signature of this operation is equivalent to [T?] -> [T?]

因此,该操作的可选元素签名与[T?]- >[T ?]

Sequence.flatMap has two overloads with specifically crafted signatures

序列。flatMap有两个特别精心制作的签名重载

func flatMap<SegmentOfResult : Sequence>(
    _ transform: (${GElement}) throws -> SegmentOfResult
) rethrows -> [SegmentOfResult.${GElement}]

func flatMap<ElementOfResult>(
    _ transform: (${GElement}) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {

The second one wins. But since you asked for array of optionals, ElementOfResult becomes Optional<String>, and transform becomes Optional<String> -> Optional<Optional<String>>.

第二个赢。但是由于您要求选择的数组,ElementOfResult变成可选的 ,转换变成可选的 ->可选的 >。

Thus when closure { $0 } returns nil, it gets lifted to Optional(nil), i.e. having .some(nil) value, not .none. Then it will pass the nil guard and appear in result.

因此,当闭包{$0}返回nil时,它将被提升到可选的(nil),即具有.some(nil)值,而不是.none。然后它将通过nil保护并显示结果。


} print(type(of:result1)) print(result1) extension Array { func sameThing() -> Array { return self.flatMap{

Consider this code...

考虑这段代码…

import Foundation

let source = ["A", "B", nil, "D"]
print(type(of:source))

let result1 = source.flatMap{ $0 }
print(type(of:result1))
print(result1)

extension Array
{
    func sameThing() -> Array
    {
        return self.flatMap{ $0 }
    }
}

let result2 = source.sameThing()
print(type(of:result2))
print(result2)

result1 is an Array<String> while result2 is an Array<Optional<String>>. But why?

resulis数组 <可选的 >。但是为什么呢?

I've tried using a Sequence instead of an array, but no luck there either.

我尝试过使用序列而不是数组,但也没有运气。

1 个解决方案

#1


1  

Your return type preserves generic type

返回类型保留泛型类型

func sameThing(separator:String = " ") -> Array

Therefore on optional elements signature of this operation is equivalent to [T?] -> [T?]

因此,该操作的可选元素签名与[T?]- >[T ?]

Sequence.flatMap has two overloads with specifically crafted signatures

序列。flatMap有两个特别精心制作的签名重载

func flatMap<SegmentOfResult : Sequence>(
    _ transform: (${GElement}) throws -> SegmentOfResult
) rethrows -> [SegmentOfResult.${GElement}]

func flatMap<ElementOfResult>(
    _ transform: (${GElement}) throws -> ElementOfResult?
) rethrows -> [ElementOfResult] {

The second one wins. But since you asked for array of optionals, ElementOfResult becomes Optional<String>, and transform becomes Optional<String> -> Optional<Optional<String>>.

第二个赢。但是由于您要求选择的数组,ElementOfResult变成可选的 ,转换变成可选的 ->可选的 >。

Thus when closure { $0 } returns nil, it gets lifted to Optional(nil), i.e. having .some(nil) value, not .none. Then it will pass the nil guard and appear in result.

因此,当闭包{$0}返回nil时,它将被提升到可选的(nil),即具有.some(nil)值,而不是.none。然后它将通过nil保护并显示结果。


} } } let result2 = source.sameThing() print(type(of:result2)) print(result2) import Founda



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: