描述§
一个(希望是)全面的 Perl 运算符列表,以及它们在 Raku 中的等效项,并在必要时说明它们之间的差异。
注意§
本文档不详细解释运算符。本文档旨在指导您从 Perl 的 perlop 文档中的运算符到 Raku 中的等效运算符。有关 Raku 等效运算符的完整文档,请参阅 Raku 文档。
运算符优先级和结合性§
Raku 中的运算符优先级表与 Perl 中有所不同,因此这里不会详细介绍。如果您需要了解 Raku 中特定运算符的优先级和结合性,请参阅 运算符优先级。
术语和列表运算符§
在本节中,Perl 的 perlop 文档中列出的作为一元和列表运算符的内容,往往可以被视为函数,例如 print 和 chdir。因此,您可以在 函数 指南中找到有关它们的信息。括号仍然用于分组。有一个注意事项:在 Raku 中,是 ,(逗号)创建列表,不是括号。所以
my = 1,2,3,4,5; # no parentheses needed.say for 1,2,3,4,5; # also no parenthesesmy = (1); # *not* a list, as there is no commamy = (1,); # a List in a scalar container
箭头运算符§
由于您通常不会在 Raku 中使用引用,因此箭头可能作为解引用运算符不太有用。但是,如果您确实需要解引用某些内容,则箭头是点。它也是方法调用的点。因此,Perl 中的 $arrayref->[7] 在 Raku 中变为 $arrayref.[7],类似地,$user->name 变为 $user.name。=> 箭头用于构建 Pair,请参阅 Pair 术语文档。
自动递增和自动递减§
与 Perl 中的工作方式相同。唯一可能的注意事项是它们通过调用 succ 方法(对于 ++)和 pred 方法(对于 --)来实现。对于内置数值类型,这不太可能做一些不寻常的事情,但自定义类型可以定义自己的 succ 和 pred 方法,因此在这些情况下,您可能应该注意 ++ 和 -- 将实际执行的操作。
指数运算§
按预期工作。Perl 中的 perlop 关于 ** 绑定比一元减号更紧密(即 "-2**4" 评估为 "-(2**4)" 而不是 "(-2)**4")的注意事项也适用于 Raku。
符号一元运算符§
与 Perl 中一样,一元 ! 和 - 分别执行逻辑和算术否定。?^ 用于按位逻辑否定,文档表明它等效于 !。需要注意的是,它们会将它们的参数分别强制转换为 Bool 和 Numeric。
一元 ~ 是 Raku 中的字符串上下文运算符,因此使用前缀 +^ 进行按位整数否定。假设是二进制补码。
+ 在 Raku 中确实有作用,它将它的参数强制转换为 Numeric 类型。
一元 \ 不再存在。如果您真的想对现有的命名变量取一个“引用”,您可以使用项目上下文,如下所示:$aref = item(@array),或者可能更熟悉地通过添加前缀 $:$aref = $@array。请注意,您实际上并没有获得引用,而是获得一个包含引用对象的标量容器。
您可以通过使用 & 符号获得对命名子例程的“引用”:$sref = &foo。匿名数组、哈希和子例程在创建时立即返回底层对象:$sref = sub { }。
绑定运算符§
=~ 和 !~ 分别被 ~~ 和 !~~ 替换。那些认为智能匹配在 Perl 中有缺陷的人会很高兴地听到它在 Raku 中工作得更好,因为更强的类型意味着更少的猜测。请参阅 智能匹配文档,以更详细地了解智能匹配在 Raku 中的工作原理。
乘法运算符§
二元运算符 *、/ 和 % 分别表示乘法、除法和取模运算,与 Perl 中相同。
二元运算符 x 在 Raku 中略有不同,并且有一个伴随运算符。print '-' x 80; 会生成一个包含 80 个连字符的字符串,但要实现 Perl 中 @ones = (1) x 80; 的行为,即生成一个包含 80 个“1”的列表,则需要使用 @ones = 1 xx 80;。
加法运算符§
二元运算符 + 和 - 分别表示加法和减法,与预期一致。
由于 . 是方法调用运算符,因此二元运算符 ~ 在 Raku 中充当连接运算符。
移位运算符§
<< 和 >> 已被 +< 和 +> 替换。
命名一元运算符§
如上所述,您可以在 函数 指南中找到这些运算符。
关系运算符§
这些运算符在 Raku 中与 Perl 中相同。
相等运算符§
== 和 != 在 Raku 中与 Perl 中相同。
<=> 和 cmp 在 Raku 中的行为有所不同。<=> 执行数值比较,但返回 Order::Less、Order::Same 或 Order::More,而不是 Perl 中的 -1、0 或 1。要获得 Perl 中 cmp 的行为(更改为返回 Order 对象,而不是整数),可以使用 leg 运算符。
cmp 会根据其参数的现有类型执行 <=> 或 leg。
~~ 是 Perl 中的智能匹配运算符,但它在 Raku 中也是仅仅匹配运算符,如上所述。有关 Raku 中智能匹配的工作原理,请参阅 智能匹配文档。
智能匹配运算符§
有关 Raku 中智能匹配的工作原理的更详细解释,请参阅 智能匹配文档。
按位与§
二元运算符 & 在 Raku 中为 +&。
按位或和异或§
按位或运算符已从 Perl 中的 | 更改为 Raku 中的 +|。类似地,按位异或运算符 ^ 为 +^,但它仅对整数进行操作。
C 风格逻辑与§
未更改。
C 风格逻辑或§
未更改。
逻辑定义或§
在 Raku 中保持为 //。返回第一个定义的操作数,否则返回最后一个操作数。此外,还有一个低优先级版本,称为 orelse。
范围运算符§
在列表上下文中,.. 充当范围运算符,无需更改。也就是说,存在可能很有用的排他范围运算符。它们是
中缀
..^,它不包含终点;中缀
^..,它不包含起点;中缀
^..^,它不包含起点和终点;前缀
^,它从零开始,不包含终点。
以下示例展示了所有上述范围运算符的效果(请注意,括号仅用于允许方法调用)
(1..^5).list; # (1 2 3 4)(1^..5).list; # (2 3 4 5)(1^..^5).list; # (2 3 4)(^5).list; # (0 1 2 3 4)
在 Perl 中,在标量上下文中,运算符 .. 和 ... 充当翻转操作符,即使它们鲜为人知且可能使用较少。这些运算符在 Raku 中分别被 ff 和 fff 替换。
条件运算符§
条件运算符 ? : 已被 ?? !! 替换。
$x = $ok ? $yes : $no; # Perl
= ?? !! ; # Raku
赋值运算符§
虽然没有完全记录,但 S03 指示数学和逻辑赋值运算符应按预期工作。一个明显的变化是 .= 在左侧的对象(也可以是类型对象)上调用一个可变方法。这允许以下有用的习惯用法
my LongClassName .= new( frobnicate => 42 ); # no need to repeat class name
这确保 $bar 只能包含 LongClassName 对象,并且不必重复(以及可能拼错)类名。
~= 是字符串连接赋值,正如您在 . 和 ~ 的变化中所预期的那样。此外,位赋值运算符可能不会被分成数字和字符串版本(&= 等,与 &.= 等),因为该功能目前在 Perl 本身中是实验性的 - 尽管,同样,这没有具体记录。
逗号运算符§
逗号运算符的工作方式与预期基本一致,但从技术上讲它创建 列表)或在函数调用中分隔参数。此外,还有一个 : 变体,它将函数调用转换为方法调用 - 请参阅 此页面。
=> 运算符或胖箭头,与 Perl 的“胖逗号”类似,它允许在其左侧使用未加引号的(普通)标识符,但在 Raku 中构造 Pair 对象,而不仅仅是充当分隔符。如果您只是尝试将一行 Perl 代码逐字翻译成 Raku,它应该按预期工作。要阅读 Raku,请查看 副词对,它将解释一种新的语法。
列表运算符(向右)§
与命名一元运算符一样,您将在 函数 中找到对它们的讨论。
逻辑非§
! 的较低优先级版本。与 ! 一样,它将参数强制转换为 Bool。
逻辑与§
&& 的较低优先级版本,与 Perl 中一样。
逻辑或和异或§
or 是 || 的低优先级版本,xor 是 ^^ 的低优先级版本。
此外,还有一个 // 的低优先级版本,称为 orelse。
引号和类似引号的运算符§
有关引号构造的所有详细信息,请参阅 引号。
有一个引号运算符允许绝对字面字符串:Q 或 「…」,尽管后者可能难以在您的键盘上找到,具体取决于您的键盘... 反斜杠转义符在 Q 引号字符串中不适用。例如,Q{This is still a closing curly brace → \} 呈现“This is still a closing curly brace → \”。
q 按照您的预期执行,允许反斜杠转义。例如,q{This is not a closing curly brace → \}, but this is → } 返回“This is not a closing curly brace → }, but this is →”。与 Perl 中一样,您可以使用单引号获得此行为。
qq 允许变量插值。但是,默认情况下,只有标量变量会被插值。要使其他变量插值,需要在它们后面加上方括号(所谓的 zen-slice)才能使它们插值。例如,@a = <1 2 3>; say qq/@a[] [email protected]/; 的结果是 "1 2 3 [email protected]"。哈希以相同的方式插值:%a = 1 => 2, 3 => 4;say "%a{}"; 的结果是使用空格分隔键值对,使用制表符分隔每个键值对中的键和值(因为这是 Pair 的标准字符串化方式,并且哈希在字符串化时充当 Pair 列表)。您也可以使用花括号在字符串中插值 Raku 代码。有关所有详细信息,请参阅 插值。
qw 的工作方式与 Perl 中相同,也可以渲染为 <...>。例如,qw/a b c/ 等效于 <a b c>。
还有一个插值的 qw 版本,即 qqw。因此,my $a = 42;say qqw/$a b c/; 将为您提供 "42 b c"。
Shell 引用可以通过 qx 获得,但您应该注意,反引号不像 Perl 中那样进行 shell 引用,并且 Perl 变量不会在 qx 字符串中插值。如果您需要在 shell 命令字符串中插值 Perl 变量,可以使用 qqx 代替。
qr 运算符已从 Raku 中移除。
tr/// 的工作方式与 Perl 中类似。唯一需要注意的是范围的指定方式不同。您不会使用范围 "a-z",而是使用 "a..z",即使用 Perl 的范围运算符。tr/// 有一个方法版本,它有更好的文档,称为 .trans。.trans 使用一对列表,如下所示:$x.trans(['a'..'c'] => ['A'..'C'], ['d'..'q'] => ['D'..'Q'], ['r'..'z'] => ['R'..'Z']);。有关 .trans 用法的更详细说明,请参阅 https://design.raku.org/S05.html#Transliteration。y/// 等效项已被移除。
Heredoc 在 Raku 中的指定方式不同。您使用 :to 与您的引用运算符一起使用,例如,q:to/END/; 将启动一个以 "END" 结尾的 heredoc。类似地,您会根据您的引用运算符获得转义和插值,即使用 Q 进行字面量,使用 q 进行反斜杠转义,使用 qq 进行插值。
I/O 运算符§
有关 Raku 中输入/输出的完整详细信息,请参阅 io。
由于 <...> 是 Raku 中的引用词构造,因此 <> 不用于从文件读取行。您可以通过从文件名创建 IO 对象或使用打开的文件句柄来实现,然后在任一情况下,都可以在其上调用 .lines。例如,my @a = "filename".IO.lines; 或 my $fh = open "filename", :r;my @a = $fh.lines;(在后一种情况下,我们使用 :r 特别是打开文件以供读取)。要以迭代方式执行此操作,您可以使用 for 循环,方法如下
for 'huge-csv'.IO.lines ->
请注意那里的 -> 的使用。这是 Block 语法的一部分,在 Raku 中,对于 if、for、while 等是必需的。
如果您想将整个文件吸收到标量中,您将 - 令人惊讶!- 使用 .slurp 方法。例如
my = "filename".IO.slurp;# ... or ...my = open "filename", :r;my = .slurp;
如 特殊变量 指南中所述,ARGV 魔法输入文件句柄已被 $*ARGFILES 替换,命令行参数的 @ARGV 数组已被 @*ARGS 替换。
无操作§
1 while foo(); 的工作方式与 Perl 中相同,但会生成警告。在 Raku 中,该习惯用法现在写为 Nil while foo();。
按位字符串运算符§
在上面单独记录,但总结一下...
按位整数取反是前缀 +^。按位布尔取反是 ?^。
按位与是 +&。
按位整数或为 +|。按位整数异或为中缀 +^。按位布尔或为 ?|。
左移和右移分别是 +< 和 +>。