本文档旨在全面(希望是)列出Perl5操作符在Perl6中的实现 , 并在必要时对差异进行说明。
本文档不会解释关于操作符的具体细节。而是旨在指导开发者快速从perl5习惯用法 迅速过渡和熟悉到perl6的语法中来。
关于perl6操作符的详细信息,请参考 Perl 6 documentation.
Perl6中运算符的优先级和Perl5有很大的差异,所以此处不在细述。相关信息,请参考 Operator Precedence。
在Perl5运算符文档中列出的一元或者列表运算符我们一般认为是函数,比如 print
和chdir
。诸如此类函数都在5to6-perlfunc.pod6,
还有圆括号依然用于分组。
由于Perl6引用出镜机会不多,所以用对其解引用场合也非常有限。而更普通存在的
对象解引用,箭头要替换成点操作。 而且对象方法调用也是点。所以在Per 6中,
Perl5中的$arrayref->[7]
被$arrayref.[7]
取代,同理,$user->name
变成了$user.name
。 胖箭头=>
现在用于构造 Pairs,详见Pair term documentation。
和Perl5一样可以使用,需要注意的一点是perl6中可以通过调用方法succ
实现++
,
pred
实现 --
的功能。直接使用++
, --
操作内置数值类型时能会造成不可
预知的结果。不过自定义类型也可以定义succ
和pred
方法。 所以在这些场合,
你需要关注++
和--
实际做了啥。
能以期望的那样工作,对比Perl5的**
运算符,Perl6中它的优先级要高于一元运算符
(例如,-2**4的值是 -(2**4),而不是(-2)**4)。
在Perl5中,一元运算符!
和-
分别是逻辑非和算术负号,可能需要注意的是它们会分别
将参数强制为Bool
以及 Numeric
。 ?^
用做按位取反,有些文档把这操作写做!
。
一元运算符~
在Perl6中是字符串连接运算符,你可以使用 +^
来完成按位取反,是个
二元运算符。
+
在Perl6中会对操作数有影响,它会强制转换它的参数为数值类型。
一元运算符\
已去除,如果你实在想引用一个已经存在的命名变量,你可以使用item上下文,
例如$aref = item(@array)
,你可以通过使用&
sigil得到一个命名子例程的引用:$sref = &foo
。 匿名数组、哈希以及子例程在创建时就会返回它们的引用。
=~
和!~
被~~
和!~~
替代,那些在对Perl5中智能匹配有顾虑的人现在可以放心使用了,
在Perl6中它们更好用了,强类型意味着不需要那么多的猜测。
二元运算符 *
, /
和%
在Perl5中分别为乘法、除法以及求余。
Perl6中的二元运算符x
稍微有些不同,同样的语句print '-' x 80;
会返回给你一个80横线
的字符串(这点上一样),但是Perl5的 @ones = (1) x 80;
返回给你一个80长度的由"1"组成的
列表,在Perl6中同样的效果你得用@ones = 1 xx 80;
。
二元运算符+
和-
分别为加法和减法,符合预期。
因为.
现在是方法调用运算符,所以二元运算符~
代替.
作为Perl6的连接运算符。
C« << »和C« >> »被+<
和+>
取代。
上面提到过,请查看5to6-perlfunc.pod6.
和Perl5表现一样。
==
和!=
表现和Perl5中相同。
<=>
和cmp
在Perl6中表现大不同。<=>
作为数值比较运算符,但返回不再是
-1
, 0
,或者1
,而是Order::Less
, Order::Same
, 或者Order::More
。
为了获取Perl5中的<cmp>一样的行为(Perl6它也返回Order对象,而非整数),你需要用
leg
运算符。
cmp
现在根据参数类型的不同可以做<=>
或者leg
的操作(兼容两种类型)。
~~
是Perl5中的智能匹配运算符,和上面提到一样,Perl6是正则匹配操作符了。 对于
Perl6中智能匹配运算符的细节,请参考https://design.perl6.org/S03.html#Smart_matching。
直接参考上面的~~
。
&
被+&
取代。
按位或从Perl5中的|
变成了+|
,类似的,异或^
被+^
取代。
无变化
无变化
Perl6中还是//,若第一个操作数已经定义则将其作为返回值,否则返回第二个操作数。
当然,它还有一个低优先级的版本orelse
。
=head2 范围运算符
在列表上下文,C<..>作为范围运算符没有变化,另外还增加了一些很有用的范围运算符。 它们是:
下面的例子显示了上面各种操作符(注意括号只是用来允许方法调用):
=begin code
(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)
=end code
在Perl 5标量上下文,C<..>和C<...>在Perl5中作为flip-flop运算符,但是鲜为人知和使用。 这些运算符在Perl6中被L<ff|/routine/ff>以及L<fff|/routine/fff>取带。
?:
被了?? !!
代替,例如Perl5中的代码$x= $ok ? $y : $z;
在 Perl6中需要这样
表达: $x = $ok ?? $y !! $z;
。
虽然还没有完全文档化,S03指出数值以及逻辑赋值运算符表现都会符合预期。 一个明显的
变化是.=
会调用等号左边对象的变异的方法。而~=
是字符连接赋值。和你预期地.
和~
变化想同。还有,按位赋值运算符貌似不再区分数值以及字符串版本(&=
, etc.,
vs. &.=
, etc.),虽然这些特性在Perl5中依然是实验性的,而且这些还没有确切的文档。
逗号运算符符合预期,但是技术上它用来创建Lists)或者分开函数调用的参数,
并且,函数调用也可以使用:
变量将函数调用转换为对象方法调用,详见this page。
运算符=>
和Perl5中的“胖箭头”类似,它允许左侧的标志符不加引用,但是在Perl6中
它用来构造Pair对象,不仅仅作为一个分隔符。如果是将Perl5的代码转换到Perl6,
它的行为不变。
如同一元命名运算符一样,请参考5to6-perlfunc.pod。
运算符!
优先级较低的版本,正如!
一样,强制将它的参数转换为Bool
。
运算符&&
的优先级较低的版本,表现和Perl5中一致。
or
是运算符||
的低优先级版本。文档中列出了xor
,没有详细文档。
另外,还有运算符//
低优先级版本orelse
。
关于引用底层结构细节,参见quoting。
有些引用运算符允许绝对字符串:Q
或者「…」
,可能由于你的键盘缘故,
这个字符可能很难找到。。。反斜杠转义在Q
引用字符串中不起作用,例如:
Q{This is still a closing curly brace → \}
结果是
"This is 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 →"。 在Perl5中,
单引号与它行为一致。
qq
允许变量的内插,然而,默认情况下只有标量会被内插替换。对使用其它类型
的变量,需要在其后加上方括号。例如:@a =<1 2 3>;say qq/@a[] example@example.com/;
结果是 "1 2 3 example@example.com"。对于哈希,内插结果是意料之外的方式:
%a = 1 => 2, 3 => 4;say "%a[]";
。 结果将会以空格分隔键值对,tab分隔
每个键值对的键和值(显式地)。 当然,你依然可以用花括号在字符串中内插
Perl6代码。 相关细节,请浏览Interpolation。
qw
跟Perl5中一样,它还可以用<...>
形式表示,例如qw/a b c/
和
<a b c>
相同。
还有一个支持内插的qw
版本(qw本身不支持内插)qqw
。例如:
my $a = 42;say qqw/$a b c/;
将会返回 "42 b c"。
shell引用现在用qx
,不过你需要注意的是``
不再像Perl5那样用于shell引用,
还有Perl变量在qx
字符串中也不做插值。如果你想在shell命令行字符串中使用内插,
你需要使用qqx
。
qr
被移除。
tr///
和Perl5类似,需要注意的一点是指定范围的方式变化了,你现在得用 "a..z",
而不是"a-z"。tr///
对应的对象方法版本,有详细的文档的,那就是.trans
,
.trans
的对象是pairs列表:例如 $x.trans(['a'..'c'] => ['A'..'C'], ['d'..'q'] => ['D'..'Q'], ['r'..'z'] => ['R'..'Z']);
。 关于.trans
详细信息,请参考
https://design.perl6.org/S05.html#Transliteration。等价的y///
已被删除。
Perl6中的heredoc有些差异,你必须用:to
作为你的引用运算符,例如q:to/END/;
将会开始一段以"END"为结尾的heredoc。同样地,根据你使用的引用运算符Q
,q
和
qq
,heredoc表现相对应的引用效果。
关于 Perl 6 的输入/输出完整细节请浏览io。
<...>
作为Perl6中的quote-word构造器一样,<>
不再用于按行读取文件,
你可以通过对IO
对象或者打开的文件句柄上调用.lines
来实现安行读文件。比如:
my @a ="filename".IO.lines;
或my $fh = open "filename", :r;my @a =$fh.lines;
(后者使用:r
表明文件用只读模式)。要用迭代的方式,你可以使用for
循环:
for 'huge-csv'.IO.lines -> $line {
# Do something with $line
}
注意这里的->
,这是结构块语法的一部分。 在Perl6中,if
, for
, while
等
都需要一个结构块。
如果你想读取整个文件内容到标量中,你可以使用.slurp
方法。例如:
my $x = "filename".IO.slurp;
# ... 或 ...
my $fh = open "filename", :r;
my $x = $fh.slurp;
在5to6-perlvar.pod有提到过,魔法输入文件句柄ARGV
已经被$*ARGFILES
取代了,命令行参数数组也被@ARGV
被@*ARGS
取代。
尽管文档中没有特别提及,但是1 while foo();
可以正常工作。
对前面提及的相关内容,总结一下:
前缀运算符 +^
执行整数的按位取反,?^
执行布尔类型的按位取反。
+&
按位与。
整型的按位或是+|
,按位异或是中缀运算符+^
,布尔型的按位或是?|
。
左移和右移是+<
及+>
。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。