请在 2024 年 Clojure 状态调查! 分享你的想法。

欢迎!请查看 关于 页面了解更多关于如何使用本网站的信息。

+5
Clojure
编辑

给定一个接口

public interface Foo {
    void bar(Object o);
}

以及该接口的代理

(proxy [Foo] []
  (bar [o] (baz o)))

当接口被更新时

public interface Foo {
  void bar(Object o);

  // java 8 default method, quote from 
  // https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
  // "Default methods enable you to add new functionality to the
  // interfaces of your libraries and ensure binary compatibility
  // with code written for older versions of those interfaces."
  default void bar(Object o, Object p) {
    bar(o);
  }
}

instanceCreatedByProxy.bar(o, p) 的调用将不会像预期那样工作。

reify 不会受到影响。

重生产仓库: https://github.com/imrekoszo/proxy-default


proxy 的文档字符串中 没有表明这种行为,我所看到的唯一与此相关的例子是 clojuredocs 上的一个示例


这很麻烦,因为它可能会阻止本来不会破坏的库升级。如果调用 proxy 的代码在自己的控制之下,可以使用 reify 代替(特别是在这是官方文档中推荐的做法)。然而,如果它在外部库中,这不是一个可行的解决方案。

这是bug还是 proxy 的已知限制?
如果是后者的情况,那么 perhaps 可以通过在文档字符串中的警告来使其更加明显,例如?


编辑
- 原始 Slack 线程链接
- 添加了到 reify 推荐的链接

2 答案

0

已被选中
感谢Alex。

我已更新了重现仓库以尝试回答Ghadi Shayban在那里的提问,但我似乎无法在问题上发表评论。

这好像在添加其他默认方法到接口时也会出现问题:https://github.com/imrekoszo/proxy-default/commit/6a2ddd2a5febdadc85adfb44957c0f010ebe7419
...