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
我有一个方法:
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