假设我有以下课程:
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;
}
我将如何以与上一课中的+
相同的方式为一个类重载一个运算符(例如,Str
)?
我想这只适用于在实例对象上调用的方法,并且对运算符使用multi operator-type:<OP>(T $lhs, T $rhs) { }
语法是正确的方法,但我不确定。
例如,在Python中,似乎在运算符(例如,operator.__add__
)和运算符(例如,+
)之后命名的特殊方法之间存在对应关系。此外,任何自定义类的运算符重载都是在类中完成的。
在Perl 6中,运算符被认为是当前语言的一部分。与当前语言相关的所有内容都是词法定义的(即my
-scoped)。因此,multi
sub是正确使用的东西。
如果将此代码放在模块中,您可能还希望使用multi
为运算符标记is export
:
multi infix:<~>(A:D $lhs, A:D $rhs) is export {
('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}
因此,use
或import
模块的用户可以使用它(use
实际上是根据import
定义的,import
将符号导入词法范围)。
虽然有些运算符默认委托给方法(例如,prefix:<+>
调用Numeric
),但两者之间没有1:1的关系,对于大多数运算符,它们的实现直接在运算符sub
中(或分布在许多multi sub
s上)。
此外,这组运算符是开放的,因此不仅限于重载现有运算符,还可以引入新运算符。当操作符的新含义与所用符号的正常语义没有明确相关时,这是鼓励的;例如,重载+
以进行矩阵添加是明智的,但对于某些不可能被视为一种加法的东西,新的运算符将是更好的选择。
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)µ"
所以是的,这是正确的方法。如果要覆盖+
,则要创建的子名称为infix:<+>
。
您还可以使用:U
“类型笑脸”为类型对象提供案例,例如:
multi infix:<~>(A:U $lhs, A:U $rhs) {
'µ'
}
希望这能回答你的问题。