Swift 编译器对我的 return 类型做了什么?它以某种方式铸造?

What is the Swift compiler doing with my return type? Is it somehow casting?

我有一个方法:

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 的 return 类型指定为 [MappedRegion],一切都会很开心(例如 let result:[MappedRegion] = ...)。

这是怎么回事?我知道原来的一行函数将结果类型推断为 [MappedRegion],所以我可能不会从惰性使用中获得太多好处。但让我感到困惑的是,这种从惰性序列自动强制转换为固定数组的操作让人想起 C 中的强制转换,我认为 Swift 没有进行强制转换?

不,没有演员表在进行。只是调用了两个不同的 flatMap 函数。 LazyMapSequence 有两个 flatMap(_:) 函数(好吧,技术上有四个,但有两个已弃用)。

在您的第一个代码块中,推断出 this 函数(因为此版本的 flatMap 具有与您的 allRegions 函数的 return类型):

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