我试图为自定义类重载逻辑or
运算符,但是它似乎不起作用。这就是我要做的:
class A { has $.a }
multi sub infix:<or> (A $a, A $b) {
"works!({$a.a}, {$b.a})"
}
say A.new(:1a) or A.new(:2a);
我期望得到works!(1, 2)
作为输出,但是我却得到了A.new(a => 1)
,这是标准or
运算符的结果。
其他运算符(and
和xor
除外)似乎对我有用:
class A { has $.a }
multi sub infix:<anything-else> (A $a, A $b) {
"works!({$a.a}, {$b.a})"
}
say A.new(:1a) anything-else A.new(:2a);
得出works!(1, 2)
。
我是在做错什么,还是无法重载标准的or
,and
,xor
运算符?
答案 0 :(得分:14)
只有编译为子例程调用的运算符可以重载。由于子例程调用的参数是在调用之前进行评估的,因此那些需要对其操作数之一进行延迟求值的运算符将在编译器中以特殊形式处理。
and
,or
,&&
和||
之类的逻辑运算符被指定为仅根据其第一个操作数的真实性来评估其第二个操作数,因此无法编译为子例程调用。
即使将它们编译为处理第二个操作数的子例程调用,也无法对第二个参数的类型进行问题中所写的多次调度,因为这些运算符的语义意味着我们可以不能立即对其进行评估,但这又意味着我们无法找到其类型来进行调度。