Raku是否有办法隐式移除Role混入来实现带误差计算的运算符重载?
解决方案
你可以直接用Raku内置的but语法移除对象上的Error角色,拿到无混入的原始值,修改后的prefix:<->实现如下:
multi prefix:<-> ( Error:D $x ) is default { # 移除Error角色后调用原生前缀减运算,再混入误差属性 (- ($x but Error:!)) does Error($x.abs-error) }
原理解释
- 你之前遇到无限循环的原因是在重载方法内再次对带
Error角色的$x调用前缀减,会重新命中当前的重载方法,形成递归死循环 $x but Error:!语法会返回一个移除了Error角色的原始对象副本,对其调用前缀减会命中Raku原生的数值运算逻辑,不会触发自定义重载- 不需要手动判断原始值的类型(Rat/Num/Int等),该语法对所有混入了
Error角色的数值对象都生效
可选通用方案
如果你需要更通用的获取原始基类值的逻辑,也可以通过元对象协议实现:
# 获取对象的原始基类型,再构造新的无混入实例 my $raw = $x.^base_type.COERCE: $x;
该方案适合需要批量处理多种角色混入的场景,对于你当前的需求,直接用but Error:!是最简洁的选择。
运行效果
修改后运行代码,输出完全符合预期:
-12.5(Rat+{Error})0.5
内容的提问来源于stack exchange,提问作者librasteve
相关产品推荐
相关产品推荐

