Swift编译器对我的返回类型做什么?是某种铸造吗?

问题描述

我有一种方法

func allRegions() -> [MappedRegion] {
    return self.items.lazy.compactMap { item in item.valveAny }.flatMap { valve in valve.regions }
}

坦率地说,我对此工作感到惊讶。我在这里做一些懒惰的事情,但是显然有一个懒惰的序列变成了一个MappedRegion序列。

然后我在做一些可怜的计时,并将功能修改为:

func allRegions() -> [MappedRegion] {
    let startTime = Date()
    let result = self.items.lazy.compactMap { item in item.valveAny }.flatMap { valve in valve.regions }
    self.sumRender += (Date() - startTime)
    return result
}

但这会产生一个错误

Cannot convert return expression of type 'LazySequence<FlattenSequence<LazyMapSequence<LazyMapSequence<LazyFilterSequence<LazyMapSequence<LazySequence<[StatusRowItem]>.Elements,ValveAbstract?>>,ValveAbstract>.Elements,[MappedRegion]>>>' (aka 'LazySequence<FlattenSequence<LazyMapSequence<LazyMapSequence<LazyFilterSequence<LazyMapSequence<Array<StatusRowItem>,Optional<ValveAbstract>>>,ValveAbstract>,Array<MappedRegion>>>>') to return type '[MappedRegion]'

最初是令人惊讶的。我发现,如果我将result的返回类型指定为[MappedRegion],那么所有人都会很高兴(例如let result:[MappedRegion] = ...)。

这是怎么回事?我知道原始的单行函数将结果类型推断为[MappedRegion],所以我可能不会从懒惰使用中获得很多好处。但是令我困惑的是,这种从惰性序列到固定数组的强制转换是否自动地让人联想到C语言中的强制转换,而我认为Swift并没有进行强制转换?

解决方法

不,没有强制转换。仅有两个不同的flatMap函数被调用。 LazyMapSequence具有两个flatMap(_:)函数(从技术上讲,四个,但不建议使用两个)。

在您的第一个代码块中,推断出this函数(因为此版本的flatMap的返回类型与您的allRegions函数的返回类型相匹配):

func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence

在第二个代码块中,推断出this函数(因为在本地变量上没有类型注释会迫使它选择以上版本的flatMap):

func flatMap<SegmentOfResult>(_ transform: @escaping (Element) -> SegmentOfResult) -> LazySequence<FlattenSequence<LazyMapSequence<LazyMapSequence<Base,Element>,SegmentOfResult>>> where SegmentOfResult : Sequence