uzl*_*xxx 12 operator-overloading perl6 raku
假设我有以下课程:
class A {
has $.val;
method Str { $!val ~ 'µ' }
}
# Is this the right way of doing it?
multi infix:<~>(A:D $lhs, A:D $rhs) {
('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}
Run Code Online (Sandbox Code Playgroud)
如何以与上一类+相同的方式重载某个类的运算符(例如)Str?
我猜这仅适用于在实例对象上调用的方法,并且multi operator-type:<OP>(T $lhs, T $rhs) { }对运算符使用语法是正确的解决方法,但我不确定。
例如,在Python中,以运算符(例如operator.__add__)和运算符(例如+)命名的特殊方法之间似乎存在对应关系。此外,自定义类的任何运算符重载都在该类内部完成。
Jon*_*ton 13
在Perl 6中,运算符被视为当前语言的一部分。与当前语言相关的所有事物均以词法定义(即my-scoped)。因此,multisub是正确的用法。
如果将此代码放在模块中,您可能还想用标记multi操作员is export:
multi infix:<~>(A:D $lhs, A:D $rhs) is export {
('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}
Run Code Online (Sandbox Code Playgroud)
这样,模块use或import该模块的用户就可以使用它(use实际上是根据定义的import,并将import符号导入到词法范围内)。
虽然有一些运算符默认情况下委托给方法(例如prefix:<+>call Numeric),但两者之间没有1:1关系,并且对于大多数运算符而言,它们的实现直接在运算符中sub(或散布在许多multi subs中)。
此外,运算符集是开放的,因此,不仅限于重载现有运算符,还可以引入新的运算符。当操作符的新含义与所用符号的常规语义没有明确关联时,鼓励使用此方法。例如,重载+来做矩阵加法是明智的,但是对于某些可能不被视为加法的事物,新的运算符将是一个更好的选择。
class A {
has $.val;
method Str { $!val ~ 'µ' }
}
multi infix:<~>(A:D $lhs, A:D $rhs) {
('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}
dd A.new(val => "A") ~ A.new(val => "B"); # "(A,B)µ"
Run Code Online (Sandbox Code Playgroud)
是的,那是正确的方法。如果要覆盖+,则要创建的子名称为infix:<+>。
您还可以使用:U“类型笑脸” 为类型对象提供大小写,例如:
multi infix:<~>(A:U $lhs, A:U $rhs) {
'µ'
}
Run Code Online (Sandbox Code Playgroud)
希望这能回答您的问题。