Raku中mixin配合运算符重载如何避免歧义调用错误
问题原因
你通过does生成的是Rat+{Physics::Error::Error}复合类型,同时匹配原生前缀负号运算符的Rat:D签名和你自定义的Error:D签名,Raku默认分派规则判定两个候选优先级一致,因此抛出歧义错误。
解决方案
方案1:运算符实现内嵌到Role中(推荐)
直接在Error角色内定义运算符方法,mixin后的实例会优先调用角色自带的方法,完全避免全局multi分派的歧义问题。
修改后的模块代码:
unit module Physics::Error; role Error is export { has Real $.abs-error; # 前缀负号运算符作为角色方法实现 method prefix:<-> () { my $result = -self.Real; # 返回新的带误差mixin的数值 return $result but Error(self.abs-error); } # 其他运算符可按相同逻辑扩展,示例加法实现: method infix:<+> ( Real:D $other ) { my $result = self.Real + $other; my $new-error = self.abs-error + ($other.does(Error) ?? $other.abs-error !! 0); return $result but Error($new-error); } }
原有调用代码无需修改即可正常运行。
方案2:给全局multi显式设置更高优先级
如果你需要保留全局multi的写法,给自定义的运算符候选加上is more specific修饰符,强制Raku分派时优先选择该候选:
unit module Physics::Error; role Error is export { has Real $.abs-error; } multi prefix:<-> ( Error:D $right where Real:D) is export is more specific { my $result = -$right.Real; return $result but Error($right.abs-error); }
两种方案返回的结果都是带Error mixin的数值类型,后续数学运算可继续同步完成误差计算。
内容的提问来源于stack exchange,提问作者librasteve
相关产品推荐
相关产品推荐

