我想要实现的是有一个适当的实施
def dynamix[A, B](a: A): A with B
我可能知道 B 是什么,但不知道 A 是什么(但如果 B 具有 self 类型,那么我可以在 A 上添加一些约束)。scala 编译器对上面的签名很满意,但我还不能弄清楚实现的样子——如果有可能的话。
我想到的一些选择:
- 使用反射/动态代理。
- 最简单的情况:A是Java级别的接口+我可以实例化B并且它没有自我类型。我想这不会太难(除非我遇到一些令人讨厌的、意想不到的问题):
创建一个新的 B (b),以及一个实现 A 和 B 并使用委托给 a 或 b 的调用处理程序的代理。 - 如果 B 不能被实例化,我仍然可以创建它的子类,并按照上面的描述进行操作。如果它也有一个 self 类型,我可能需要在这里和那里进行一些委托,但它仍然可以工作。
- 但是如果 A 是一个具体的类型而我找不到合适的接口呢?
- 我会遇到更多问题吗(例如与线性化相关的问题,或有助于 Java 互操作性的特殊结构)?
- 最简单的情况:A是Java级别的接口+我可以实例化B并且它没有自我类型。我想这不会太难(除非我遇到一些令人讨厌的、意想不到的问题):
- 使用一种包装而不是 mixin 并返回 B[A],a 可以从 b 访问。
不幸的是,在这种情况下,调用者需要知道嵌套是如何完成的,如果混合/包装多次完成(D[C[B[A]]]),这可能会非常不方便,因为它需要找到正确的嵌套级别来访问所需的功能,所以我不认为这是一个解决方案。 - 实现编译器插件。我对它的经验为零,但我的直觉是它不会是微不足道的。我认为 Kevin Wright 的autoproxy插件有一个类似的目标,但它还不足以解决我的问题(还没有?)。
您还有其他可行的想法吗?你会推荐哪种方式?期待什么样的“挑战”?
还是我应该忘记它,因为当前的 Scala 约束是不可能的?
我的问题背后的意图:假设我有一个业务工作流程,但它并不太严格。有些步骤有固定的顺序,但有些没有,但最后都必须完成(或者其中一些需要进一步处理)。
一个更具体的例子:我有一个 A,我可以添加 B 和 C。我不在乎先完成哪个,但最后我需要一个 A 和 B 和 C。
评论:我对 Groovy 了解不多,但突然出现了这个问题,我想它或多或少与我想要的相同,至少是概念性的。