Swift 编译器无法解决泛型的递归使用

标签 swift generics chain-of-responsibility

我正在尝试在 Swift 中实现责任链模式。

public class Chain<T, U> {
    private var command: (T?, (U?) -> Void) -> Void
    private var runCommand: (() -> Void)?
    private var nextCommand: ((U?) -> Void)?

    private init(command: (T?, (U?) -> Void) -> Void) {
        self.command = command
    }

    private func next(u: U?) {
        self.nextCommand?(u)
    }

    func then<V>(command: (U?, (V?) -> Void) -> Void) -> Chain<U, V> {
        let c = Chain<U, V>(command: command)

        self.nextCommand = { command($0, c.next) }
        c.runCommand = self.runCommand

        return c
    }

    func endWith(command: (U?) -> Void) {
        self.nextCommand = command
        self.runCommand!()
    }

    static func build<V>(command: ((V?) -> Void) -> Void) -> Chain<AnyObject, V> {
        let c = Chain<AnyObject, V>(command: { _, next in command(next) })
        c.runCommand = { command(c.next) }
        return c
    }
}

我的类不会引发任何编译错误,但一个简单的用例(例如下面的用例)不起作用。它会引发以下错误: 错误:无法使用类型为 '((_?) -> ()) 的参数列表调用 'endWith' ;需要类型为“((U?) -> Void)”的参数列表

有什么想法吗?

Chain.build { next in
    print("Foo")
    next("Bar")
}
.then { o, next in
    print(o)
    next(15)
}
.endWith { o in
    print(o)
}

我知道这是 Swift 中泛型使用的一个边缘情况。然而,由于不可能显式地特化泛型类型,所以到目前为止我还没有找到任何解决方案。

最佳答案

编译器无法推断示例中的类型。您只需在不明确的地方指定它们即可:

Chain<String,Int>.build { next in
  print("Foo")
  next("Bar")
  }
  .then { (o: String?, next: Int? -> Void) in
    print(o)
    next(15)
  }
  .endWith { o in
    print(o)
}

关于Swift 编译器无法解决泛型的递归使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34141857/

相关文章:

ios - MPNowPlayingInfoCenter 不显示详细信息

design-patterns - 责任链与装饰器设计模式

ios - 来自两个文本字段的值被添加到第一个

macos - 如何快速监控文件夹中的新文件?

iOS - NSNotificationCenter 延迟

使用泛型进行 Java 和 Kotlin 转换。失去类型安全

Java 泛型 - 我在这里做错了什么?

c# - 在 C# 中遇到继承和泛型问题

code-analysis - FxCop(/VS2010 代码分析),可以将 IDisposable 的方法结果标记为 "callers responsibility now"吗?

java - 责任链记录