问题标签 [double-dispatch]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
46 浏览

r - R中的双重调度:S4 vs vctrs库

如果我们想在 R 中实现双重调度方法,我们目前有两个选项可供选择:

我特别指算术运算符,例如 + 或 *。

它们在性能方面如何比较?他们的间接费用是否具有可比性?

0 投票
1 回答
55 浏览

r - 将 vctrs 构建的类放入包中时错误的双重调度方法

我创建了一个新类来使用 vctrs 打印百分比,如 https://vctrs.r-lib.org/articles/s3-vector.html中所述。当我获取 .R 文件时,它运行良好。但是当我使用 devtools 构建包时,使用 vec_arith 实现的基本操作不再起作用:

但是,类似的情况运行良好:转换很好;vec_math 也可以,可以做sum(pct(0.5, 1L) + pct(0.25, 2L))

我制作了一个可重现的示例,其中包含使用 devtools 2.3.2 和 vctrs 0.3.6 加载带有 percent 类的小包所需的代码。

  1. 我们使用 devtools 创建一个名为 percenterror 的新包:

在这个包的 RStudio 项目内的控制台上,我们声明依赖关系并创建一个新的 .R 文件:

  1. 让我们在打开的 .R 文件中复制以下代码,并使用 roxygen 标签生成 NAMESPACE :

如果我们这样做library(vctrs)并获取此文档, 则pct(0.5) + pct(0.25)可以正常工作。

  1. 但是,回到控制台,我们创建文档并加载包:

在这里,添加不再起作用:

但是找到了方法:

该方法似乎与正确的泛型相关联:

vec_arith.numeric 方法适用于 pct :

但事实并非如此,vec_arith_pct方法不适用于 numeric :

当我们使用 rlang::last_trace() 运行错误跟踪时,我们发现该 pct + pct操作实际上并没有转到正确的方法,甚至不关心上面定义的函数,因为vec_arith.default用于代替vec_arith.pct

出了什么问题,该怎么做才能使它起作用?我已经尝试在没有 vctrs:: 调用的情况下使用 ou,导入或不导入 NAMESPACE 中的几乎所有内容,但无法找到发生了什么。

谢谢

0 投票
0 回答
32 浏览

r - 使用 S3 对象进行双重调度,一个泛型与两个泛型

假设您尝试使用 S3 模拟双重调度,并且您正在两种方法之间做出选择:

示例 1:一个泛型f()

示例 2:两个泛型g()h()

测试等效性

  1. 您会说以下哪个示例是更好的选择?
  2. 一个另一个更像双重调度,还是它们本质上是等价的?
  3. 哪个会为用户提供更好的可扩展性/灵活性?

我能说的唯一区别是,在示例 1 中,直接f.foo调用UseMethod("f.foo", arg2),而在示例 2 中,g.foo调用h然后调用UseMethod("h", arg2). 所以简而言之,第二种方法只有一个额外的函数调用。

也许第二个示例在代码结构中更容易跟踪,但它们本质上是等价的。

当然,最终会更好的是类结构和最适合包的 API 的东西

0 投票
1 回答
27 浏览

r - `vec_arith` 包的双重分派错误

我正在尝试实施该vctrs软件包,但具体而言,我正在尝试使vec_arith双重调度正常工作。

如果我将它加载到全局环境中,下面的示例代码可以工作,但是如果从它自己的包命名空间中调用,它似乎找不到正确的调度。

如果你只用这个文件构建一个包,有人可以告诉我这是否可以重现吗?

我不知道它是否重要,但描述文件如下所示:

0 投票
1 回答
60 浏览

java - 在 Java 中使用访问者模式进行双重调度

我有这个架构: 架构访客模式

XMLFormulaFormatter中,我需要Constant(在我的 Main 类中创建的实例)的实例的值。

我在Constant课堂上有这个方法:

我在XMLFormulaFormatter课堂上试过这段代码:

但当然它并没有给我我正在看的内容,因为我想获得Constant...的特定实例的值

我也尝试过以下format()方法XMLFormulaFormatter

但结果与预期相同。

关于如何获取特定实例的值的任何想法Constant

谢谢!

0 投票
2 回答
72 浏览

typescript - 如何从映射变量中获取具体类型?

我有以下代码:

我在最后一个最后一个错误:

return colliderFn(s1, s2);

我明白为什么我会收到错误(我认为),但我不知道如何解决它。我基本上是想通过一个映射变量来实现一种干净的双重调度方式,这样每个形状组合都会返回一个有效的函数,我可以调用它来查看它们是否发生冲突。

有没有办法做到这一点?如果是这样,怎么做?

0 投票
1 回答
62 浏览

java - 访客模式和双重调度

我知道这是一个很好的领域,但我有一个具体的问题......我保证。

在静态类型、面向对象的世界中花费的时间很少,我最近在阅读Crafting Interpreters时遇到了这种设计模式。虽然我理解这种模式允许在一组定义良好的现有类型(类)上实现可扩展的行为(方法) ,但我并没有完全将其描述为双重分派问题的解决方案,至少在没有一些额外假设的情况下并非如此. 我认为它更多地是对表达式问题进行权衡,您可以将封闭类型换成开放方法。

在我见过的大多数示例中,您最终都会得到这样的结果(无耻地从很棒的Clojure 设计模式中窃取)

在这里,我们有一组类型(消息和活动)可能是关闭的或不经常更改的,还有一组我们希望为扩展而开放的方法(访问者)。现在我感到困惑的是,在大多数示例中,它们将展示如何在不触及现有类的情况下实现其他访问者,例如:

然后毫不客气地暗示这是“双重调度”,但事实并非如此。这里accept动态分派 的子类型Item,但在方法内accept通过visit方法重载静态分派给传入的访问者。所以我们有一个单独的调度Item,然后其中的“第二个”静态调度accept实际上是关于选择一个行为(方法)来调用该Item类型。只有一种“类型”被发送,而不是两种——第二种是行为。

当我想到双重分派时,我想到了一个按两个参数的类型分派的函数。一种行为,两种类型。

对我来说,这与访问者模式略有不同,访问者模式允许将任何行为集扩展到现有类,但这些行为不一定都代表export上面四个示例中的相同行为——它们可以是任何东西。如果我们添加另一个访问者,它可能代表导出,但也可能不代表。从 API 层你只是调用accept方法并相信传入的访问者会做你想做的事,不管它可能是什么。

我看错了吗?