函数使用不明确 (Swift 4)
Ambiguous use of functions (Swift 4)
我一直在试图找出为什么下面的代码不明确...
public func product <T1: Sequence, T2: Sequence> (_ sequence1: T1, _ sequence2: T2) ->
AnySequence<(T1.Element, T2.Element)> {
return AnySequence(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}
)
}
public func product <T1: LazySequenceProtocol, T2: LazySequenceProtocol> (_ sequence1: T1, _ sequence2: T2) ->
LazySequence<AnySequence<(T1.Element, T2.Element)>> {
return AnySequence(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}
).lazy
}
...当我用两个惰性序列调用它并调用 makeIterator
EXAMPLE.
_ = product([1, 2].lazy, [3, 4].lazy).makeIterator()
然而,下面的代码没有这种歧义...
public struct Product2Sequence <T1: Sequence, T2: Sequence>: Sequence {
public typealias Element = (T1.Element, T2.Element)
public typealias Iterator = AnyIterator<Element>
private let iterator: Iterator
internal init (_ sequence1: T1, _ sequence2: T2) {
self.iterator = AnyIterator(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}.makeIterator()
)
}
public func makeIterator () -> Iterator {
return self.iterator
}
}
public struct LazyProduct2Sequence <T1: LazySequenceProtocol, T2: LazySequenceProtocol>: LazySequenceProtocol {
public typealias Element = (T1.Element, T2.Element)
public typealias Iterator = AnyIterator<Element>
private let iterator: Iterator
internal init (_ sequence1: T1, _ sequence2: T2) {
self.iterator = AnyIterator(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}.makeIterator()
)
}
public func makeIterator () -> Iterator {
return self.iterator
}
}
public func product <T1: Sequence, T2: Sequence> (_ sequence1: T1, _ sequence2: T2) -> Product2Sequence<T1, T2> {
return Product2Sequence(sequence1, sequence2)
}
public func product <T1: LazySequenceProtocol, T2: LazySequenceProtocol> (_ sequence1: T1, _ sequence2: T2) ->
LazyProduct2Sequence<T1, T2> {
return LazyProduct2Sequence(sequence1, sequence2)
}
...当我用两个惰性序列调用它并调用 makeIterator
EXAMPLE.
_ = product([1, 2].lazy, [3, 4].lazy).makeIterator()
我的推理是惰性序列同时符合 LazySequenceProtocol
和 Sequence
,所以类型系统不知道选择哪个 product
。但是根据这个定义,第二个版本也不应该工作。
我正在使用 Swift 4.0.
是什么让第二个版本起作用?
这是一个已在 4.1 中解决的错误(请参阅 https://bugs.swift.org/browse/SR-4509)。过去类型求解器无法在 Sequence
和 LazySequenceProtocol
之间进行选择,因为前者显然符合后者。
我不能确定为什么你的第二个版本确实适用于 4.0 并且没有证据支持我的假设,但我猜这与类型求解器能够从更多信息中获取更多信息有关具体 return 类型。
无论如何,现在首选LazySequenceProtocol
,以便尽可能长时间地保持懒惰。您的代码在 Swift 4.1.
中按预期工作
我一直在试图找出为什么下面的代码不明确...
public func product <T1: Sequence, T2: Sequence> (_ sequence1: T1, _ sequence2: T2) ->
AnySequence<(T1.Element, T2.Element)> {
return AnySequence(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}
)
}
public func product <T1: LazySequenceProtocol, T2: LazySequenceProtocol> (_ sequence1: T1, _ sequence2: T2) ->
LazySequence<AnySequence<(T1.Element, T2.Element)>> {
return AnySequence(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}
).lazy
}
...当我用两个惰性序列调用它并调用 makeIterator
EXAMPLE.
_ = product([1, 2].lazy, [3, 4].lazy).makeIterator()
然而,下面的代码没有这种歧义...
public struct Product2Sequence <T1: Sequence, T2: Sequence>: Sequence {
public typealias Element = (T1.Element, T2.Element)
public typealias Iterator = AnyIterator<Element>
private let iterator: Iterator
internal init (_ sequence1: T1, _ sequence2: T2) {
self.iterator = AnyIterator(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}.makeIterator()
)
}
public func makeIterator () -> Iterator {
return self.iterator
}
}
public struct LazyProduct2Sequence <T1: LazySequenceProtocol, T2: LazySequenceProtocol>: LazySequenceProtocol {
public typealias Element = (T1.Element, T2.Element)
public typealias Iterator = AnyIterator<Element>
private let iterator: Iterator
internal init (_ sequence1: T1, _ sequence2: T2) {
self.iterator = AnyIterator(
sequence1.flatMap { element1 in
sequence2.map { element2 in
(element1, element2)
}
}.makeIterator()
)
}
public func makeIterator () -> Iterator {
return self.iterator
}
}
public func product <T1: Sequence, T2: Sequence> (_ sequence1: T1, _ sequence2: T2) -> Product2Sequence<T1, T2> {
return Product2Sequence(sequence1, sequence2)
}
public func product <T1: LazySequenceProtocol, T2: LazySequenceProtocol> (_ sequence1: T1, _ sequence2: T2) ->
LazyProduct2Sequence<T1, T2> {
return LazyProduct2Sequence(sequence1, sequence2)
}
...当我用两个惰性序列调用它并调用 makeIterator
EXAMPLE.
_ = product([1, 2].lazy, [3, 4].lazy).makeIterator()
我的推理是惰性序列同时符合 LazySequenceProtocol
和 Sequence
,所以类型系统不知道选择哪个 product
。但是根据这个定义,第二个版本也不应该工作。
我正在使用 Swift 4.0.
是什么让第二个版本起作用?
这是一个已在 4.1 中解决的错误(请参阅 https://bugs.swift.org/browse/SR-4509)。过去类型求解器无法在 Sequence
和 LazySequenceProtocol
之间进行选择,因为前者显然符合后者。
我不能确定为什么你的第二个版本确实适用于 4.0 并且没有证据支持我的假设,但我猜这与类型求解器能够从更多信息中获取更多信息有关具体 return 类型。
无论如何,现在首选LazySequenceProtocol
,以便尽可能长时间地保持懒惰。您的代码在 Swift 4.1.