描述§
一个(希望是)全面的 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();
。
按位字符串运算符§
在上面单独记录,但总结一下...
按位整数取反是前缀 +^
。按位布尔取反是 ?^
。
按位与是 +&
。
按位整数或为 +|
。按位整数异或为中缀 +^
。按位布尔或为 ?|
。
左移和右移分别是 +<
和 +>
。