我已将代码从函数式编程语言翻译为 Swift,并且在通过变量进行验证时效果很好。但是,我在测试时遇到错误,原因是 Streamable 和任何 Streamable 不兼容。这是上下文:
Streamable 协议充当泛型或声明符合协议的变量的类型约束。相反,任何 Streamable 都表示符合 Streamable 的类型,在闭包中用于捕获或返回此类类型。
如何利用 Streamable 来实现unnyNumberStream?
顺便说一句,我让它变得如此简单易懂,所以应该不难理解。
protocol Streamable {
associatedtype Element
func next() -> (Element, Self)
}
struct OnesStream: Streamable {
func next() -> (Int, OnesStream) {
return (1, OnesStream())
}
}
final class LazyNaturalStream: Streamable {
private var current: Int
init(start: Int = 1) {
self.current = start
}
func next() -> (Int, LazyNaturalStream) {
let result = current
current += 1
return (result, LazyNaturalStream(start: current))
}
}
func streamForNSteps<S: Streamable>(_ s: S, _ n: Int) -> [S.Element] {
if n == 0 {
return []
} else {
let next = s.next()
return [next.0] + streamForNSteps(next.1, n - 1)
}
}
let globalLazyNaturalStream = LazyNaturalStream()
let funnyNumberStream: any Streamable = {
struct FunnyStream: Streamable {
var localLazyNaturalStream = globalLazyNaturalStream
func next() -> (Int, FunnyStream) {
let currentValue = localLazyNaturalStream.next()
if currentValue.0 % 5 == 0 {
return (-currentValue.0, FunnyStream(localLazyNaturalStream: currentValue.1))
} else {
return (currentValue.0, FunnyStream(localLazyNaturalStream: currentValue.1))
}
}
}
return FunnyStream()
}()
// Example usage
// [1, 2, 3, 4, -5, 6, 7, 8, 9, -10, 11, 12, 13, 14, -15, 16]
let a = streamForNSteps(funnyNumberStream, 16)
上面的示例工作得很好,测试用例才是问题所在。
测试用例:
final class hw4Test: XCTestCase {
func testFunnyNumberStream() throws {
// Act
let caseOneResult = streamForNSteps(funnyNumberStream, 0)
let caseTwoResult = streamForNSteps(funnyNumberStream, 16)
let caseThreeResult = streamForNSteps(funnyNumberStream, 5)
// Assert
XCTAssertEqual(caseOneResult, []) // Type 'Any' cannot conform to 'Equatable'
XCTAssertEqual(caseTwoResult, [1, 2, 3, 4, -5, 6, 7, 8, 9, -10, 11, 12, 13, 14, -15, 16]) // Type 'Any' cannot conform to 'Equatable'
XCTAssertEqual(caseThreeResult, [1, 2, 3, 4, -5]) // Type 'Any' cannot conform to 'Equatable'
}
}
欢迎任何解释!!!
let funnyNumberStream: any Streamable = { ... }
这表明
funnyNumberStream
不仅可以由任何Streamable
类型实现,而且可以由任何Streamable
类型实现任何Element
类型。你的意思似乎是它应该是Int
的流。这最容易用主要关联类型来表达:
protocol Streamable<Element> { // <--- Add <Element> as the primary associated type
associatedtype Element
func next() -> (Element, Self)
}
然后您可以将变量限制为返回
Streamable
的 Int
:
let funnyNumberStream: any Streamable<Int> = { ... }