操作符優(yōu)先級(jí)
S03-operators/arith.t lines 46–342
S03-operators/precedence.t lines 5–200
Perl 6 擁有和 Perl 5 同等數(shù)量的優(yōu)先級(jí)級(jí)別铺浇,但是它們散布在不同的地方。這兒孤紧,我們列出了從最緊湊到最松散的級(jí)別于购,每一級(jí)別還有幾個(gè)例子:
最高優(yōu)先級(jí)到最低優(yōu)先級(jí):
A Level Examples
= ===== ========
N Terms 42 3.14 "eek" qq["foo"] $x :!verbose @$array
L Method postfix .meth .+ .? .* .() .[] .{} .<> .?? .:: .= .^ .:
N Autoincrement ++ --
R Exponentiation **
L Symbolic unary ! + - ~ ? | || +^ ~^ ?^ ^
L Multiplicative * / % %% +& +< +> ~& ~< ~> ?& div mod gcd lcm
L Additive + - +| +^ ~| ~^ ?| ?^
L Replication x xx
X Concatenation ~
X Junctive and & (&) ∩
X Junctive or | ^ (|) (^) ∪ (-)
L Named unary temp let
N Structural infix but does <=> leg cmp .. ..^ ^.. ^..^
C Chaining infix != == < <= > >= eq ne lt le gt ge ~~ === eqv !eqv (<) (elem)
X Tight and &&
X Tight or || ^^ // min max
R Conditional ?? !! ff fff
R Item assignment = => += -= **= xx= .=
L Loose unary so not
X Comma operator , :
X List infix Z minmax X X~ X* Xeqv ...
R List prefix print push say die map substr ... [+] [*] any Z=
X Loose and and andthen
X Loose or or xor orelse
X Sequencer <== ==> <<== ==>>
N Terminator ; {...} unless extra ) ] }
下面使用的兩個(gè) !
符號(hào)通常表示任意一對(duì)兒擁有相同優(yōu)先級(jí)的操作符室谚, 上表指定的二元操作符的結(jié)合性解釋如下(其中 A 代表結(jié)合性, associativities ):
結(jié)合性 Meaning of $a ! $b ! $c
===== =========================
L left ($a ! $b) ! $c
R right $a ! ($b ! $c)
N non ILLEGAL
C chain ($a ! $b) and ($b ! $c)
X list infix:<!>($a; $b; $c)
對(duì)于一元操作符, 這解釋為:
結(jié)合性 Meaning of !$a!
===== =========================
L left (!$a)!
R right !($a!)
N non ILLEGAL
(在標(biāo)準(zhǔn) Perl 中沒(méi)有能利用結(jié)合性的一元操作符脾拆,因?yàn)樵诿恳粌?yōu)先級(jí)級(jí)別中品腹, 標(biāo)準(zhǔn)操作符要么一貫地是前綴岖食,要么是后綴。)
注意列表結(jié)合性(X)只在同一操作符之間有效舞吭。如果兩個(gè)擁有不同列表結(jié)合性的操作符擁有相同的優(yōu)先級(jí)泡垃,它們彼此間就會(huì)被認(rèn)為是非結(jié)合性的,必須使用圓括號(hào)來(lái)消除歧義羡鸥。
S03-operators/precedence.t lines 211–245
例如蔑穴, X
交叉操作符和 Z
拉鏈操作符 都有 "list infix" 優(yōu)先級(jí),但是:
@a X @b Z @c
是非法的惧浴,它必須寫(xiě)成下面的任意一種:
(@a X @b) Z @c
@a X (@b Z @c)
如果僅有的列表結(jié)合性操作符的實(shí)現(xiàn)是二進(jìn)制的, 那么它會(huì)被當(dāng)作是右結(jié)合性的存和。
標(biāo)準(zhǔn)的優(yōu)先級(jí)層級(jí)嘗試和它們的結(jié)合性相一致, 但是用戶定義的操作符和優(yōu)先級(jí)級(jí)別可以在同一優(yōu)先級(jí)級(jí)別上混合右結(jié)合性和左結(jié)合性操作符。如果在同一個(gè)表達(dá)式中不小心使用了有沖突的操作符, 那么操作符彼此之間會(huì)被認(rèn)為是非結(jié)合性的, 并且必須使用圓括號(hào)來(lái)消除歧義。
如果你沒(méi)有在上面看見(jiàn)你喜歡的操作符, 下面的章節(jié)會(huì)包含所有按優(yōu)先級(jí)排列的操作符捐腿。這兒描述了基本的操作符纵朋。
Term precedence
這實(shí)際上不真的是優(yōu)先級(jí), 但是它在這里是因?yàn)闆](méi)有操作符的優(yōu)先級(jí)比 term 高. 查看 S02 獲取各種 terms 的更詳盡的描述. 這里有一些例子:
- Int 字面量
42
- Num 字面量
3.14
- 不能插值的 Str 字面量
'$100'
- 能插值的 Str 字面量
"Answer = $answer\n"
- 通用的 Str 字面量
q["$100"]
qq["$answer"]
- Heredoc
qq:to/END/
Dear $recipient:
Thanks!
Sincerely,
$me
END
- 數(shù)組構(gòu)造器
[1,2,3]
[ ]
里面提供了列表上下文. 技術(shù)上講, 它實(shí)際上提供了一個(gè) semilist
上下文, 即一系列分號(hào)分割的語(yǔ)句, 每條語(yǔ)句都在列表上下文中解釋, 然后被連接成最終的列表.
- 散列構(gòu)造器
{ }
{ a => 42 }
{ }
里面要么是空的, 要么是以 pair 或 散列 開(kāi)頭的單個(gè)列表, 否則你必須使用 hash( )
或 %( )
代替.
- Closure
{ ... }
如果出現(xiàn)在語(yǔ)句那兒, 會(huì)立即執(zhí)行。 否則會(huì)延遲內(nèi)部作用域的求值茄袖。
- 捕獲構(gòu)造器
\(@a,$b,%c)
代表還不知道它的上下文的參數(shù)列表的抽取,
- 符號(hào)化變量
$x
@y
%z
$^a
$?FILE
&func
&div:(Int, Int --> Int)
- 符號(hào)作為上下文化函數(shù)
$()
@()
%()
&()
- quote-like 記號(hào)中的 Regexes
/abc/
rx:i[abc]
s/foo/bar/
- 轉(zhuǎn)換
tr/a..z/A..Z/
注意范圍使用 ..
而非 -
.
- 類型名
Num
::Some::Package
- 由圓括號(hào)環(huán)繞的子表達(dá)式
(1+2)
- 帶括號(hào)的函數(shù)調(diào)用
a(1)
一個(gè)項(xiàng)后面立即跟著一個(gè)圓括號(hào)化的表達(dá)式總是被當(dāng)作函數(shù)調(diào)用操软, 即使那個(gè)標(biāo)識(shí)符也含有前綴意義, 所以那種情況下你從來(lái)不用擔(dān)心優(yōu)先級(jí)宪祥。因此:
not($x) + 1 # means (not $x) + 1
- Pair 構(gòu)造器
:limit(5)
:!verbose
- 簽名字面量
:(Dog $self:)
- 使用隱式調(diào)用者的方法調(diào)用
.meth # call on $_
.=meth # modify $_
注意這只能出現(xiàn)在需要項(xiàng)(term)的地方聂薪。需要后綴的地方它就是后綴。如果需要中綴操作符(即, 在項(xiàng)后面, 之間是空格), .meth 就是語(yǔ)法錯(cuò)誤蝗羊。(.meth 形式在那兒是被允許的因?yàn)橛幸粋€(gè)和方法調(diào)用形式在語(yǔ)義上等價(jià)但是允許在 = 號(hào)和方法名之間于空格存在的特殊 .= 中綴賦值操作符)藏澳。
- Listop (leftward)
4,3, sort 2,1 # 4,3,1,2
就像 Perl 5 中一樣, 列表操作符對(duì)于它左側(cè)的表達(dá)式看起來(lái)像一個(gè)項(xiàng)(term), 所以它比左側(cè)的逗號(hào)綁定的緊湊點(diǎn), 比右側(cè)的逗號(hào)綁定的松散點(diǎn)。-- 查看下面的列表前綴優(yōu)先級(jí)肘交。
方法后綴優(yōu)先級(jí)
所有的方法后綴都以一個(gè)點(diǎn)開(kāi)頭, 盡管對(duì)于下標(biāo)來(lái)說(shuō), 點(diǎn)號(hào)是可選的. 因?yàn)檫@些是最緊密的操作符, 你可以看到一系列方法調(diào)用作為單獨(dú)的項(xiàng), 這個(gè)項(xiàng)僅僅要表達(dá)一個(gè)復(fù)雜的名字.
- 標(biāo)準(zhǔn)的單個(gè)分發(fā)方法調(diào)用
$obj.meth
- 標(biāo)準(zhǔn)單個(gè)分發(fā)方法調(diào)用的變體
$obj.+meth
$obj.?meth
$obj.*meth
除了普通的 .
方法調(diào)用之外, 還有 .*
, .?
, 和 .+
變體來(lái)控制如何處理多個(gè)同名的相關(guān)方法.
- 類限定的方法調(diào)用
$obj.::Class::meth
$obj.Class::meth # same thing, 假設(shè)預(yù)先定義了 Class
就跟 Perl 5 一樣, 告訴分發(fā)器(dispatcher)從哪個(gè)類開(kāi)始搜索, 而不正好是那個(gè)被調(diào)用的方法笆载。
- 可變方法調(diào)用
$obj.=meth
.= 操作符執(zhí)行了對(duì)左側(cè)對(duì)象的就地修改。
- 元方法調(diào)用
$obj.^meth
.^
操作符調(diào)用了類的元方法(class metamethod); foo.^bar 是 foo.HOW.bar
的簡(jiǎn)寫(xiě)涯呻。
- 像方法一樣的后環(huán)綴
$routine.()
$array.[]
$hash.{}
$hash.<>
$hash.??
不帶點(diǎn)的這些形式有同樣的優(yōu)先級(jí).
- 帶點(diǎn)形式的其它后綴操作符
$x.++ # postfix:<++>($x)
- 帶點(diǎn)形式的其它前綴操作符
$x.:<++> # prefix:<++>($x)
- 有一個(gè)特殊的非中綴操作符 infix:<.> 所以
$foo . $bar
總是會(huì)返回編譯時(shí)錯(cuò)誤來(lái)標(biāo)示用戶應(yīng)該使用中綴操作符 infix<~> 代替凉驻。這用于捕獲正在學(xué)習(xí) Perl 6 的 Perl 5 程序員可能會(huì)犯的錯(cuò)誤。
自增優(yōu)先級(jí)
就像在 C 中一樣复罐,這些操作符增加或減少正在談?wù)摰哪莻€(gè)對(duì)象的值涝登,根據(jù)操作符在前面還是在后面。還是像 C 中一樣效诅,在同一個(gè)表達(dá)式中多個(gè)對(duì)單個(gè)可變對(duì)象的引用可能導(dǎo)致未定義行為除非顯式地插入了某些序列操作符胀滚。請(qǐng)查看 "Sequence points"。
至于 Perl 6 中得所有后綴操作符乱投,項(xiàng)(term) 和它的后綴之間不允許有空格咽笼。請(qǐng)查看 S02 來(lái)了解為什么,還有怎么使用 "unspace" 來(lái)應(yīng)急這個(gè)約束戚炫。
和可變方法一樣剑刑,所有這些操作符被分派為操作符數(shù)的類型并返回一個(gè)同類型的結(jié)果,但是只有(不可變的)值存儲(chǔ)在可變?nèi)萜髦袝r(shí)双肤,它們?cè)谥殿愋蜕喜攀呛戏ǖ氖┨汀H欢瑸榱酥С滞ㄓ玫牧?xí)語(yǔ)茅糜,一個(gè)裸的未定義值(在一個(gè)合適的標(biāo)量容器中)是被允許把自身修改成 Int 類型的:
say $x unless %seen{$x}++;
Str (在一個(gè)合適的容器中)的增加和 Perl 5 類似七芭,但是被稍微推廣了一點(diǎn)。Perl 6 會(huì)掃描前面不是 '.' 字符的字符串中得最后的字母數(shù)字序列蔑赘。不像 Perl 5 那樣狸驳,這個(gè)字母數(shù)字序列不需要錨定到字符串的開(kāi)頭预明,也不需要以字母數(shù)字符開(kāi)頭;字符串中匹配 <!after '.'> <rangechar>+
字母數(shù)字的最后的序列被增加而不管它前面是什么锌历。
<rangechar>
字符類被定義為那種字符的子集(subset)贮庞,Perl 知道怎么在范圍(range)中增加它,就像下面定義的那樣:
額外的匹配增加了兩個(gè)好處:對(duì)于典型的增長(zhǎng)文件名的用法究西,你不必?fù)?dān)心路徑名或擴(kuò)展名:
$file = "/tmp/pix000.jpg";
$file++; # /tmp/pix001.jpg, 不是 /tmp/pix000.jph
也許更重要的是, 如果你恰好增長(zhǎng)了一個(gè)以小數(shù)結(jié)尾的字符串,Perl 6 也能應(yīng)對(duì)自如:
$num = "123.456";
$num++; # 124.456, not 123.457
字符位置增加自然范圍內(nèi)任何Unicode范圍被認(rèn)為代表了數(shù)字0 . .9或被認(rèn)為是一個(gè)完整的周期性字母的(一例)(Unicode)腳本物喷。只在codepoints腳本,代表他們的字母表,形成一個(gè)周期獨(dú)立于其他字母可能使用卤材。(此規(guī)范延緩這種腳本的用戶,以確定適當(dāng)?shù)闹芷诘男偶?。我們?nèi)我舛xASCII字母不相交與其他腳本,使用范圍的字符,但是字母點(diǎn)綴ASCII字母是不允許的峦失。
如果在這樣一個(gè)范圍中當(dāng)前字符是字符串位置中最后的字符,它包裝的第一個(gè)字符范圍和發(fā)送一個(gè)“攜帶”的位置了,然后那個(gè)位置是增加的范圍扇丛。當(dāng)且僅當(dāng)最左邊的位置是筋疲力盡的范圍,一個(gè)額外的字符相同的范圍是插入到持有套利以相同的方式作為Perl 5,所以遞增(zz99)“變成”(aaa00)zz和遞增(99)“變成”(100 aa)”。
> my $a = "99zz"
> $a++ # 99zz
> $a++ # 100aa
> my $b = 'zz99'
> $b++ # zz99
> $b++ # aaa00
下面的 Unicode 范圍是某些可能的 rangechar 范圍尉辑。對(duì)于字母我們有這樣的范圍:
A..Z # ASCII uc
a..z # ASCII lc
'Α'..'Ω' # Greek uc
α..ω # Greek lc (presumably skipping C<U+03C2>, final sigma)
?..? # 希伯來(lái)
etc. # (XXX out of my depth here)
> my @a = 'Α'..'Ω' # Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ ? Σ Τ Υ Φ Χ Ψ Ω
對(duì)于數(shù)字我們有這樣的范圍:
0..9 # ASCII
?..? # 阿拉伯語(yǔ)-印度語(yǔ)
?..? # 天城文
?..? # 孟加拉語(yǔ)
'?'..'?' # 古木基文
?..? # 古吉拉特文
?..? # 奧里亞語(yǔ)
等等.
> my @b = '?'..'?' # ? ? ? ? ? ? ? ? ? ?
某些其它非書(shū)寫(xiě)用的 0..9 范圍也可以被增長(zhǎng)帆精,例如:
?..? # 上標(biāo) (note, cycle includes latin-1 chars)
'?'..'?' # 下標(biāo)
0..9 # 全角數(shù)字
> my @f = '?'..'?' # ? ? ? ? ? ? ? ? ? ?
Ⅰ..Ⅻ # clock roman numerals uc
ⅰ..? # clock roman numerals lc
?..? # circled digits/numbers 0..50
?..? # parenthesized lc
?..? # die faces 1..6
'?'..'?' # dingbat negative circled 1..10
etc.
注意: 對(duì)于 Perl 中實(shí)際的范圍, 你需要把上面的字符用引號(hào)括起來(lái):
'?'..'?' # circled digits/numbers 0..50
my @d = '?'..'?'
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
my @e = '?'..'?' # ? ? ? ? ? ? ? ? ? ?
If you want to future-proof the top end of your range against further Unicode additions, you may specify it as "whatever":
'?'..* # circled digits/numbers up to current known Unicode max
prefix:<|>, 將對(duì)象展開(kāi)為參數(shù)列表
| $capture
把Capture 值的內(nèi)容(或 Capture-like)插值進(jìn)當(dāng)前的參數(shù)列表中, 就像它們被字面地指定那樣隧魄。
prefix:<||>, 將對(duì)象展開(kāi)為分號(hào)列表
|| $parcel
把 Parcel(或其它有順序的值)的元素插值到當(dāng)前參數(shù)列表中就像它們被字面地指定一樣, 由分號(hào)分割, 即, 以多維級(jí)別卓练。在列表中的列表上下文之外使用該操作符是錯(cuò)誤的; 換句話說(shuō), 它必須被綁定到 **
(slice)參數(shù)上而非吞噬參數(shù)*
上。
infix:<div>, 整除
$numerator div $denominator
> 3 div 2 # 1
> 13 div 2 # 6
而
> 13 div 2.4
報(bào)錯(cuò):
Cannot call infix:<div>(Int, Rat); none of these signatures match:
(Int:D \a, Int:D \b)
(int $a, int $b --> int)
in block <unit> at <unknown file>:1
infix:<%>, modulo
$x % $y
重復(fù)操作符
infix:<x>, 字符串/緩沖區(qū) 復(fù)制(或者重復(fù)/拷貝)
$string x $count
在字符串上下文中計(jì)算左邊的參數(shù)购啄,重復(fù)結(jié)果字符串值由右側(cè)參數(shù)指定的倍數(shù)次襟企,然后不管上下文,把結(jié)果作為單個(gè)連接好的字符串返回狮含。
如果重復(fù)次數(shù)小于 1顽悼,則返回空字符串。重復(fù)次數(shù)不可以是 *
几迄,因?yàn)?Perl 6 不支持無(wú)窮字符串蔚龙。(至少,還沒(méi)有...)然而注意映胁,有一天無(wú)窮字符串可能使用 cat($string xx *
) 來(lái)模仿木羹,在這種情況下,$string x *
可能是它的簡(jiǎn)寫(xiě)屿愚。
'a' x *; # WhateverCode.new()
my $a = 'a' x *; # WhateverCode.new()
say $a; # WhateverCode.new()
say $a(12); # 可以傳遞參數(shù)汇跨!, 結(jié)果為 aaaaaaaaaaaa
infix:<xx>, 表達(dá)式重復(fù)操作符
@list xx $count # 如果 $count 是 * ,則返回一個(gè)無(wú)限列表 (懶惰的妆距,因?yàn)榱斜砟J(rèn)是懶惰的 )
rand xx *; # infinite supply of random numbers
[ 0 xx $cols ] xx $rows # distinct arrays, not the same row replicated
> my @random= rand xx *;
> @random[0] # 0.510689533871727
> @random[0] # 0.510689533871727
> @random[1] # 0.993102039714483
> @random[2] # 0.177400471499773
> @random[12]
字符串連接
infix:<~>, 字符串 /緩沖 連接
$x ~ $y
范圍對(duì)象創(chuàng)建
$min .. $max
$min ^.. $max
$min ..^ $max
$min ^..^ $max
逗號(hào)操作符優(yōu)先級(jí)
- infix:<,> 參數(shù)分隔符
1, 2, 3, @many
不像 Perl5 穷遂,逗號(hào)操作符從來(lái)不返回最后一個(gè)值(在標(biāo)量上下文中它返回一個(gè)列表)
- infix:<:>, 調(diào)用者標(biāo)記
say $*OUT: "howdy, world" # howdy, world
say($*OUT: "howdy, world") # howdy, world
push @array: 1,2,3
push(@array: 1,2,3)
\($object: 1,2,3, :foo, :!bar)
冒號(hào)操作符就像逗號(hào)那樣解析,但是它把左邊的參數(shù)標(biāo)記為調(diào)用者娱据,這會(huì)把函數(shù)調(diào)用轉(zhuǎn)換為方法調(diào)用蚪黑。它只能在參數(shù)列表或捕獲的第一個(gè)參數(shù)身上使用盅惜,用在其它地方會(huì)解析失敗。當(dāng)用在捕獲中時(shí)忌穿,尚不知道?捕獲會(huì)被綁定到哪個(gè)簽名上抒寂;如果綁定到一個(gè)非方法的簽名身上,調(diào)用者僅僅轉(zhuǎn)換成第一個(gè)位置參數(shù)掠剑,就像冒號(hào)是一個(gè)逗號(hào)一樣屈芜。
為了避免和其它的冒號(hào)形式混淆,冒號(hào)中綴操作符后面必須跟上空格或終止符朴译。它前面可以有空格也可以沒(méi)有空格井佑。
注意:在下面把中綴操作符和冒號(hào)區(qū)別開(kāi):
@array.push: 1,2,3
@array.push(1,2,3): 4,5,6
push(@array, 1,2,3): 4,5,6
這是把普通函數(shù)或方法轉(zhuǎn)換為列表操作符的特殊形式。 這種特殊形式只在點(diǎn)語(yǔ)法形式的方法調(diào)用后被識(shí)別眠寿, 或者在方法或函數(shù)調(diào)用的右圓括號(hào)之后被識(shí)別躬翁。這種特殊形式不允許其間有空格,但是下一個(gè)參數(shù)的前面要有空格盯拱。如果可能的話在所有其它情況下盒发,冒號(hào)會(huì)被解析為副詞的開(kāi)始,否則會(huì)被解析為調(diào)用者標(biāo)記(上面描述的中綴操作符狡逢。)
這種特殊形式不允許介于中間的空格宁舰, 但是允許在下一個(gè)參數(shù)之前有空格。 在所有情況下甚侣, 冒號(hào)會(huì)被盡可能地解析為副詞的開(kāi)頭明吩,或者調(diào)用者標(biāo)記者(上面描述的中綴)
冒號(hào)的另一種特殊方式是, 允許正好在參數(shù)列表的右側(cè)圓括號(hào)之后為圓括號(hào)括住的參數(shù)列表添加 listop 參數(shù),附帶條件是你被允許把 .foo(): 1,2,3
縮短為 .foo: 1,2,3
.(但是僅限于方法調(diào)用殷费, 因?yàn)槠胀ǖ暮瘮?shù)不需要把處于第一個(gè)位置的冒號(hào)轉(zhuǎn)換為 listop印荔, 空格就夠了。 如果你嘗試使用冒號(hào)擴(kuò)展函數(shù)名最好把它看作標(biāo)簽详羡。)
foo $obj.bar: 1,2,3 # special, means foo($obj.bar(1,2,3))
foo $obj.bar(): 1,2,3 # special, means foo($obj.bar(1,2,3))
foo $obj.bar(1): 2,3 # special, means foo($obj.bar(1,2,3))
foo $obj.bar(1,2): 3 # special, means foo($obj.bar(1,2,3))
foo($obj.bar): 1,2,3 # special, means foo($obj.bar, 1,2,3)
foo($obj.bar, 1): 2,3 # special, means foo($obj.bar, 1,2,3)
foo($obj.bar, 1,2): 3 # special, means foo($obj.bar, 1,2,3)
foo $obj.bar : 1,2,3 # infix:<:>, means $obj.bar.foo(1,2,3)
foo ($obj.bar): 1,2,3 # infix:<:>, means $obj.bar.foo(1,2,3)
foo $obj.bar:1,2,3 # 語(yǔ)法錯(cuò)誤
foo $obj.bar :1,2,3 # 語(yǔ)法錯(cuò)誤
foo $obj.bar :baz # 副詞, means foo($obj.bar(:baz))
foo ($obj.bar) :baz # 副詞, means foo($obj.bar, :baz)
foo $obj.bar:baz # extended identifier, foo( $obj.'bar:baz' )
foo $obj.infix:<+> # extended identifier, foo( $obj.'infix:<+>' )
foo: 1,2,3 # label at statement start, else infix
這個(gè)故事的寓意是:如果你不知道冒號(hào)是怎樣結(jié)合的仍律,就使用空格或圓括號(hào)讓它清晰。
- List infix precedence 列表中綴優(yōu)先級(jí)
列表中綴操作符都有列表結(jié)合性实柠,這意味著水泉,同一個(gè)中綴操作符是同步起作用的,而不是一個(gè)接著一個(gè)窒盐。不同的操作符被認(rèn)為是非結(jié)合性的草则,為了明確,必須用括號(hào)括起來(lái)蟹漓。
- infix:<Z>, the zip operator
1,2 Z 3,4 # (1,3),(2,4)
> 2,5,7 [Zmin] 3,4,5 # 兩兩比較, 2 4 5
> my @a=3,6,9 # 3 6 9
> my @b=4,5,10 # 4 5 10
> @a [Zmin] @b # 3 5 9
> my @a = (1,2,9,3,5) # 1 2 9 3 5
> my @b = (2,3,5,1,9) # 2 3 5 1 9
> my @c = (2,3,4,5,1) # 2 3 4 5 1
> @a [Zmin] @b [Zmin] @c # 1 2 4 1 1
> @a [Zmax] @b [Zmax] @c # 2 3 9 5 9
- infix:<minmax>, minmax 操作符
@a minmax @b
返回@a和@b中最小值和最大值的一個(gè)范圍炕横。
> my @a = 2,4,6,8;
> my @b = 1,3,5,7,9;
> @a minmax @b # 1..9
- infix:<X>, 交叉操作符
S03-metaops/cross.t lines 6–19
1,2 X 3,4 # (1,3), (1,4), (2,3), (2,4)
和 zip 操作符相比, X 操作符返回元素交叉后的列表葡粒。例如份殿,如果只有 2 個(gè)列表膜钓,第一個(gè)列表中取一個(gè)元素和第二個(gè)列表中取一個(gè)元素組成 pair 對(duì)兒,第二個(gè)元素變化的最迅速卿嘲。
最右邊的列表先遍歷完颂斜。因此, 你寫(xiě):
<a b> X <1 2>
你會(huì)得到:
('a', '1'), ('a', '2'), ('b', '1'), ('b', '2')
這在平的上下文會(huì)變成一個(gè)展平的列表拾枣,在 list of list 上下文中會(huì)變成列表中的列表
say flat(<a b> X <1 2>).perl # ("a", "1", "a", "2", "b", "1", "b", "2").list
say lol(<a b> X <1 2>).perl # (("a", "1"), ("a", "2"), ("b", "1"), ("b", "2"))
這個(gè)操作符是列表結(jié)合性的沃疮,所以:
1,2 X 3,4 X 5,6
生成
(1,3,5),(1,3,6),(1,4,5),(1,4,6),(2,3,5),(2,3,6),(2,4,5),(2,4,6)
另一方面,如果任一列表為空梅肤,你會(huì)得到一個(gè)空列表忿磅。
盡管X兩邊的列表可能是無(wú)限的,在操作符 X的右邊使用無(wú)限列表可能會(huì)產(chǎn)生意想不到的結(jié)果凭语,例如:
<a b> X 0..*
會(huì)產(chǎn)生
('a',0), ('a',1), ('a',2), ('a',3), ('a',4), ('a',5), ...
并且你絕對(duì)不會(huì)到達(dá) 'b'。如果你左側(cè)的列表只包含單個(gè)元素撩扒,然而似扔,這可能有用,尤其是如果 X 用作元操作符時(shí)搓谆〕椿裕看下面。
say lol(<a b> X <1 2>).perl # ("a", "1", "a", "2", "b", "1", "b", "2")
Cross metaoperators 交叉操作符
@files X~ '.' X~ @extensions
1..10 X* 1..10
@x Xeqv @y
等等
一個(gè)常見(jiàn)的用法是讓一個(gè)列表只含有單個(gè)元素在操作符 X 的一邊或另一邊:
@vector X* 2; # 每個(gè)元素都乘以 2
$prefix X~ @infinitelist; # 在無(wú)限列表的每個(gè)元素前面前置一個(gè)元素
> my $prefix = ' - '
> my @a =<1 2 3 4 5>
> $prefix X~ @a # - 1 - 2 - 3 - 4 - 5
這時(shí)右邊有一個(gè)無(wú)限列表是可以的泉手。