范圍和范圍迭代器語法
..
范圍操作符有各種在兩端帶有 ^
符號的變體以表明把那個(gè)端點(diǎn)排除在范圍之外泣矛。 它總會產(chǎn)生一個(gè) Range 對象吮廉。 Range 對象是不可變的许师, 主要用于匹配間隔洋闽。
1..2 是從1到2包含端點(diǎn)的間隔瓤球, 而 1..2 不包含端點(diǎn)但是匹配任何在它倆之間的實(shí)數(shù)。
對于不同類型的數(shù)字參數(shù)咏连, 范圍會被強(qiáng)制為更寬的類型盯孙,所以:
1 .. 1.5
被看作為:
1.0 .. 1.5
這些強(qiáng)制由 multi 簽名定義。(其它類型可能有不同的強(qiáng)制策略祟滴。)特別要說明的是振惰, 使用 Range 作為末端是非法的:
0 ..^ 10 # 0 .. 9
0 .. ^10 # ERROR
如果范圍右側(cè)是非數(shù)字類型, 那么右側(cè)的參數(shù)被強(qiáng)轉(zhuǎn)為數(shù)字垄懂, 然后按上面那樣使用骑晶。
因此,第二個(gè)參數(shù)中的 Array 類型會被假定用作數(shù)字草慧, 如果左側(cè)的參數(shù)是數(shù)字的話:
0 ..^ @x # okay
0 ..^ +@x # same thing
對于字符串也類似:
0 .. '1.5' # okay
0 .. +'1.5' # same thing
Whatever 類型也支持代表 -Inf/+Inf桶蛔。 如果端點(diǎn)之一是一個(gè) WhateverCode, 那么范圍會被引導(dǎo)為另一個(gè) WhateverCode。
Range 對象支持代表它們的左側(cè)和右側(cè)參數(shù)的 .min 和 .max 方法漫谷。 .bounds 方法返回一個(gè)含有那兩個(gè)值的列表以代表間隔仔雷。 Ranges 不會自動反轉(zhuǎn):
2..1 總是一個(gè) null 范圍。(然而舔示, 序列操作符 .. 能夠自動反轉(zhuǎn)碟婆,看下面。)
在 Range 的每個(gè)端點(diǎn)處惕稻, Range 對象支持代表排除(有)或包含(沒有)的 .excludes_min
and .excludes_max
方法竖共。
Range | .min | .max | .excludes_min | .excludes_max
-----------+------+------+---------------+------------
1..10 | 1 | 10 | Bool::False | Bool::False
2.7..^9.3 | 2.7 | 9.3 | Bool::False | Bool::True
'a'^..'z' | 'a' | 'z' | Bool::True | Bool::False
1^..^10 | 1 | 10 | Bool::True | Bool::True
如果用在列表上下文中, Range 對象返回一個(gè)迭代器俺祠, 它產(chǎn)生一個(gè)以最小值開頭公给,以最大值結(jié)尾的序列。
任一端點(diǎn)可以使用 ^ 排除掉锻煌。因此 1..2 產(chǎn)生 (1,2) 但是 1^..^2
等價(jià)于 2..1 并不產(chǎn)生值妓布, 就像 () 做的那樣。要指定一個(gè)倒數(shù)的序列宋梧, 使用反轉(zhuǎn):
reverse 1..2
reverse 'a'..'z'
作為選擇匣沼, 對于數(shù)字序列, 你能使用序列操作符代替范圍操作符:
100,99,98 ... 0
100, *-1 ... 0 # same thing
換句話說捂龄,任何用作列表的 Range 會假定 .succ 語義释涛, 絕對不會是 .pred
語義。 沒有其它的增量被允許倦沧;如果你想通過某個(gè)不是 1 的增量數(shù)字來增加一個(gè)數(shù)字序列唇撬,
你必須使用 ... 序列操作符。(Range 操作符的 :by
副詞因此被廢棄了展融。)
0, *+0.1 ... 100 # 0, 0.1, 0.2, 0.3 ... 100
只有正念叨的類型支持 .succ 方法的 Range 才能被迭代窖认。如果它不支持, 任何迭代嘗試都會失敗。
一元區(qū)間
一元操作符 ^ 生成一個(gè)從 0 直到 其參數(shù)(不包括該參數(shù))的區(qū)間扑浸。所以 ^4 等價(jià)于 0..^4.
for ^4 { say $_ } # 0, 1, 2, 3
范圍的自動填充
[這一節(jié)是推斷的烧给,并且可能會在 6.0 中被忽略.]
因?yàn)樵?item 上下文中 Range 對象通常是無意義的,用作標(biāo)量操作符的 Range 對象一般會嘗試把操作分配給終點(diǎn)并返回另外一個(gè)適當(dāng)?shù)男薷倪^的 Range 代替喝噪。
很像兩個(gè)項(xiàng)的連結(jié)(junction), 但是只使用合適的間隔語義础嫡。 (值得注意的這種自動線程化的例外包括 infix:<~~>
, 它是做智能匹配的, 還有 prefix:<+>
, 它返回范圍的長度。) 因此如果你想使用長度而不是終點(diǎn)來做切片酝惧, 你可以這樣說:
@foo[ start() + ^$len ]
它是下面這種形式的簡寫:
@foo[ start() + (0..^$len) ]
它有點(diǎn)等價(jià)于:
@foo[ list do { my $tmp = start(); $tmp ..^ $tmp+$len } ]
換句話說榴鼎,數(shù)值化的操作符和其它有順序的類型通常被重載以在 Range 身上完成某些有意義的事情。
鏈?zhǔn)奖容^
S03-operators/relational.t lines 102–238
Perl 6 支持比較操作符的自然擴(kuò)展, 它允許多個(gè)操作數(shù):
if 1 < $a < 100 { say "Good, you picked a number *between* 1 and 100." }
if 3 < $roll <= 6 { print "High roll" }
if 1 <= $roll1 == $roll2 <= 6 { print "Doubles!" }
如果第一個(gè)比較失敗了則產(chǎn)生比較短路鏈:
S03-operators/short-circuit.t lines 236–297
1 > 2 > die("this is never reached");
鏈子中得每個(gè)參數(shù)至多會被求值一次:
S03-operators/short-circuit.t lines 226–235
1 > $x++ > 2 # $x 只精確地增長一次
注意: 任何以 < 開頭的操作符必須在前面擁有空格晚唇,否則它會被解釋為散列的下標(biāo)巫财。
調(diào)用者標(biāo)記
當(dāng)使用 Perl 6 方法調(diào)用的「間接對象」語法時(shí)追加的 :
標(biāo)記了調(diào)用者(invocant)。下面的兩個(gè)語句是等價(jià)的:
$hacker.feed('Pizza and cola');
feed $hacker: 'Pizza and cola';
冒號也可以用在普通方法調(diào)用中以標(biāo)示它應(yīng)該被解析為列表操作符:
$hacker.feed: 'Pizza and cola';
這個(gè)冒號是一個(gè)單獨(dú)的令牌(token)哩陕。副詞前面的冒號不是單獨(dú)的令牌(token)翁涤。因此,在最長令牌(longest-token)規(guī)則下,
$hacker.feed:xxx('Pizza and cola');
被標(biāo)記為應(yīng)用到方法上作為它的「最高層級的在前面的操作符」("toplevel preceding operator")的副詞:
$hacker.feed :xxx('Pizza and cola');
不是作為 .feed
參數(shù)列表中的 xxx sub:
$hacker.feed: xxx('Pizza and cola'); # wrong
如果你兩種意義的冒號你都想要萌踱,為了既提供副詞又提供某種位置參數(shù), 你必須放置兩次冒號:
$hacker.feed: :xxx('Pizza and cola'), 1,2,3;
(因?yàn)轭愋偷脑蛩枰芽崭穹旁跇?biāo)簽的冒號之后。)
要特別注意因?yàn)楦痹~的優(yōu)先級:
1 + $hacker.feed :xxx('Pizza and cola');
會把 :xxx
副詞應(yīng)用到 +
操作符上, 而不是應(yīng)用到方法調(diào)用上号阿。這是不可能成功的并鸵。
S03-operators/adverbial-modifiers.t lines 7–201
流操作符
S03-feeds/basic.t lines 6–163
新的操作符 ==>
和 <==
就像Unix里的管道一樣,但是它作用于函數(shù)或語句扔涧,接受并返回列表.因?yàn)檫@些列表由不相關(guān)聯(lián)的對象組成并不流動园担, 我們把它們叫做喂食(feed)操作符而非管道。例如:
@result = map { floor($^x / 2) },
grep { /^ \d+ $/ },
@data;
也能寫成向右偏的流操作符:
@data ==> grep { /^ \d+ $/ }
==> map { floor($^x / 2) }
==> @result;
或者使用左方向的流操作符:
@result <== map { floor($^x / 2) }
<== grep { /^ \d+ $/ }
<== @data;
每一種形式更清晰地表明了數(shù)據(jù)的流動枯夜。查看 S06 了解更多關(guān)于這兩個(gè)操作符的信息弯汰。
元操作符
Perl 6 的操作符被極大地規(guī)范化了,例如湖雹,通過分別在數(shù)字咏闪、字符串和布爾操作符前前置 +
、~
摔吏、?
來表明按位操作是作用在數(shù)字鸽嫂、字符串還是單個(gè)位身上。但是那只是一種命名約定征讲,并且如果你想添加一個(gè)新的按位 ?
操作符据某, 你必須自己添加 +?
, ~?
, 和 ??
操作符。 類似地诗箍,范圍中排除末端的脫字符(^
)在那里只是約定而已癣籽。
和它相比, Perl 6 有 8 個(gè)標(biāo)準(zhǔn)的元操作符用于把已存在的給定操作符轉(zhuǎn)換為相關(guān)的更強(qiáng)大的操作符(或者至少不是一般的強(qiáng)大)。換句話說筷狼,這些元操作符正是高階函數(shù)(以其它函數(shù)作為參數(shù)的函數(shù))的便捷形式瓶籽。
包含元操作符的結(jié)構(gòu)被認(rèn)為是 "metatokens", 這意味著它們不受普通匹配規(guī)則的制約桑逝, 盡管它們的部件受制約棘劣。 然而,像普通的 tokens 那樣楞遏, metatokens 不允許在它們的子部件之間有空格茬暇。
賦值操作符
S03-operators/autovivification.t lines 4–111
C 和 Perl 程序員對于賦值操作符已經(jīng)司空見慣了。(盡管 .= 操作符現(xiàn)在意味著在左邊對象的身上調(diào)用一個(gè)可變方法寡喝, ~= 是字符串連結(jié)糙俗。)
大部分非關(guān)系中綴操作符能通過后綴 = 被轉(zhuǎn)換為對應(yīng)的賦值操作符。
A op= B;
A = A op B;
否定關(guān)系操作符
任何能返回 Bool 值的中綴關(guān)系操作符都可以通過前置一個(gè) !
將它轉(zhuǎn)換為否定的關(guān)系操作符预鬓。有幾個(gè)關(guān)系操作符還有傳統(tǒng)的便捷寫法:
Full form Shortcut
--------- --------
!== !=
!eq ne
但是大部分關(guān)系操作符沒有傳統(tǒng)的便捷寫法:
!~~
!<
!>=
!ge
!===
!eqv
!=:=
為了避免 !!
操作符迷惑視線巧骚, 你不可以修改任何已經(jīng)以!
開頭的操作符。
否定操作符的優(yōu)先級和基(base)操作符的優(yōu)先級相同格二。
你只可以否定那些返回 Bool 值的操作符劈彪。 注意諸如 ||
和 ^^
的邏輯操作符不返回 Bool 值, 而是返回其中之一的操作數(shù)。
翻轉(zhuǎn)操作符
在任意中綴操作符上前置一個(gè) R,會翻轉(zhuǎn)它的兩個(gè)參數(shù)寞忿。例如之斯,反向比較:
- Rcmp
- Rleg
- R<=>
任何翻轉(zhuǎn)操作符的優(yōu)先級和根操作符的優(yōu)先級是一樣的。結(jié)合性沒有被翻轉(zhuǎn)。
[R-] 1,2,3 # produces 2 from 3 - (2 - 1)
要得到另外一種效果,可以先翻轉(zhuǎn)列表:
[-] reverse 1,2,3 # produces 0
超運(yùn)算符
Unicode 字符 ?
(\x[BB]) 和 ?
(\x[AB]) 和它們的 ASCII連字 >>
和 <<
用于表示列表操作
, 它作用于列表中的每個(gè)元素, 然后返回單個(gè)列表(或數(shù)組)作為結(jié)果. 換句話說, 超運(yùn)算符在 item 上下文中計(jì)算它的參數(shù), 但是隨后將操作符分派到每個(gè)參數(shù)身上,結(jié)果作為列表返回疮绷。
當(dāng)書寫超運(yùn)算符時(shí), 里面不允許出現(xiàn)空格嚣潜, 即冬骚, 兩個(gè) "hyper" 標(biāo)記之間不能有空格, 并且該操作符是能修改參數(shù)的郑原。 在外面空格策略和它的 base 操作符相同唉韭。 同樣地, 超運(yùn)算符的優(yōu)先級和它的 base 操作符相同犯犁。 這意味著對于大部分操作符属愤,你必須使用圓括號括起你使用逗號分割的列表。酸役。
例如:
-? (1,2,3); # (-1, -2, -3)
(1,1,2,3,5) ?+? (1,2,3,5,8); # (2,3,5,8,13)住诸,尖括號都朝內(nèi)時(shí)驾胆,兩邊列表元素的個(gè)數(shù)必須相同
(如果你發(fā)現(xiàn)你自己這樣做了, 問問你自己是否真的在使用對象或列表贱呐; 在后一種情況中丧诺, 可能其它的諸如 Z 或 X 的元操作符更合適, 并且不需要括號)
一元超運(yùn)算符(要么前綴奄薇,要么后綴)只有一個(gè) hyper 標(biāo)記驳阎, 位于它的參數(shù)那邊, 而中綴操作符通常在參數(shù)的每一邊以表明有兩個(gè)參數(shù)馁蒂。
一元超運(yùn)算符
一元超運(yùn)算符的意思取決于操作符是否是結(jié)構(gòu)非關(guān)聯(lián)的操作符呵晚。 大部分操作符不是結(jié)構(gòu)的。
對于中綴操作符沫屡,如果兩者其中之一的一個(gè)參數(shù)的長度不夠饵隙,那么 Perl 會「提高」它,但是只有你把 hyper 標(biāo)記「尖」的那一端指向它時(shí)沮脖,Perl 才會提升長度不夠的那一端金矛。
(3,8,2,9,3,8) >>->> 1; # (2,7,1,8,2,7)
@array ?+=? 42; # add 42 to each element
實(shí)際上,對于一個(gè)無序的諸如 Bag 的類型來說勺届,一個(gè)提升過的標(biāo)量是唯一能工作于該類型中的東西:
Bag(3,8,2,9,3,8) >>->> 1; # Bag(2,7,1,8,2,7) === Bag(1,2,2,7,7,8)
# Cannot modify an immutable Bag
> Bag(3,8,2,9,3,8) # Bag 的用法以改變
bag(9, 8(2), 3(2), 2)
換句話說驶俊,把小于號那端指向一個(gè)參數(shù)告訴超運(yùn)算符在那邊做我想要做的(dwim, do what i means)。如果你不知道一邊或是另一邊會是 underdimensioned免姿,那么你可以在兩邊都做我想做的:
$left ?*? $right
注意:如果你擔(dān)心 Perl 會被像這樣的東西所迷惑:Note: if you are worried about Perl getting confused by something like this:
func ?*?
那么你無需擔(dān)心废睦,因?yàn)椴幌胫暗陌姹荆?Perl 6 從來不會猜測下一個(gè)東西是一個(gè)項(xiàng)(term)還是一個(gè)操作符。在這種情況下养泡,它總是期望一個(gè)項(xiàng)除非 func 被預(yù)先定義為一個(gè)類型或值的名字。
升級絕對不會發(fā)生在 hyper 的「鈍」的那一端上奈应。如果你這樣寫:
$bigger ?*? $smaller
$smaller ?*? $bigger
那么會拋出異常澜掩,而如果你這樣寫:
$foo ?*? $bar
那么你要求形狀的兩邊是一樣長的,否則會拋出異常杖挣。
對于所有 hyper dwimminess肩榕,如果運(yùn)算符的另一邊期望列表的地方出現(xiàn)的是一個(gè)標(biāo)量,那么那個(gè)標(biāo)量會被當(dāng)做一個(gè)重復(fù)了 *
次的那個(gè)元素的列表惩妇。
一旦我們有兩個(gè)列表要處理株汉,那么我們不得不決定使兩邊的元素長度相一致。如果兩邊都是 dwimmy歌殃,那么較短的那個(gè)列表會重復(fù)盡可能多的次數(shù)以使元素的個(gè)數(shù)合適乔妈。
如果只有一邊是 dwimmy,那么那一端的列表只會被增長或截?cái)嘁赃m應(yīng)另一邊的 non-dwimmy 的那個(gè)列表氓皱。
不管從數(shù)組的形狀的 dwim 是強(qiáng)制的還是自然發(fā)生的路召,一旦選擇了 dwim 的那一端勃刨,在 dwimmy 端的 dwim 語義總是:
下面是一些例子:
(1,2,3,4) ?+? (1,2) # always error,尖括號都朝內(nèi)時(shí)股淡,兩邊元素必須個(gè)數(shù)相同
(1,2,3,4) ?+? (1,2) # 2,4,4,6 rhs dwims to 1,2,1,2
(1,2,3) ?+? (1,2) # 2,4,4 rhs dwims to 1,2,1
(1,2,3,4) ?+? (1,2) # 2,4 lhs dwims to 1,2
(1,2,3,4) ?+? (1,2) # 2,4,4,6 rhs dwims to 1,2,1,2
(1,2,3) ?+? (1,2) # 2,4,4 rhs dwims to 1,2,1
(1,2,3) ?+? 1 # 2,3,4 rhs dwims to 1,1,1
當(dāng)使用一元
操作符時(shí), 你總是把鈍的那端對準(zhǔn)單個(gè)運(yùn)算對象, 因?yàn)闆]有出現(xiàn)重復(fù)的東西:
@negatives = -? @positives;
@positions?++; # Increment all positions
@positions.?++; # Same thing, dot form
@positions?.++; # Same thing, dot form 報(bào)錯(cuò)
@positions.?.++; # Same thing, dot form
@positions\ .?\ .++; # Same thing, unspace form
@objects.?.run();
("f","oo","bar").?.chars; # (1,2,3)
注意方法調(diào)用實(shí)際上是后綴操作符, 而非中綴操作符, 所以, 你不能在點(diǎn)號后面放上一個(gè) ?
超運(yùn)算符在嵌套數(shù)組中是被遞歸地定義的身隐, 所以:
-? [[1, 2], 3] # [-?[1, 2], -?3] 得到 -1 -2 -3
# == [[-1, -2], -3]
[[1, 2], 3] ?+? [4, [5, 6]] # [[1,2] ?+? 4, 3 ?+? [5, 6]],得到 5 6 8 9
# == [[5, 6], [8, 9]]
超運(yùn)算符也能作用于散列唯灵,就像作用于數(shù)組一樣贾铝。
%foo ?+? %bar;
得到兩個(gè)鍵的交集(對應(yīng)的鍵值相加)
> my %foo = "Tom" => 98, "Larry" => 100, "Bob" => "49";
("Tom" => 98, "Larry" => 100, "Bob" => "49").hash
> my %bar = "Tom" => 98, "Larry" => 100, "Vivo" => 86
("Tom" => 98, "Larry" => 100, "Vivo" => 86).hash
> %foo ?+? %bar
("Tom" => 196, "Larry" => 200).hash
而:
> %foo ?+? %bar;
("Tom" => 196, "Larry" => 200, "Bob" => 49, "Vivo" => 86).hash
得到兩個(gè)鍵的并集(鍵值相加)
不對稱的 hypers 也有用; 例如, 如果你說:
%outer ?+? %inner;
只有在 %outer 中已經(jīng)存在的 %inner 鍵才會出現(xiàn)在結(jié)果中.
> my %inner = "a" => 11;
> my %outer = "a" => 9, "b" => 12;
> %outer ?+? %inner # a => 20, b => 12
然而埠帕,
%outer ?+=? %inner;
假設(shè)你想讓 %outer 擁有鍵的并集垢揩,累加鍵值
> my %inner = "a" => 11;
> my %outer = "a" => 9, "b" => 12;
> %outer ?+=? %inner; # a => 20, b => 12
> say %outer # a => 20, b => 12
> say %inner # a => 11
注意, hypers 允諾你不必關(guān)心處理以怎樣的順序發(fā)生搞监,只保證結(jié)果的結(jié)構(gòu)和輸入的形式保持一致水孩。從系統(tǒng)角度也不能保證操作是并行化的。
高效的并行化要求某種程度的不帶更多額外工作的工作分割琐驴,系統(tǒng)被允許平衡并行處理的惰性需求俘种。
例如, 一個(gè)算法想把一個(gè)列表分成2個(gè)等長的子列表是不會起作用的绝淡, 如果你不得不提前計(jì)算好列表長度宙刘, 因?yàn)槟悴皇强偰苡?jì)算出長度±谓停可以采取各種方法:
按需切換要并行處理的群組悬包, 或交錯(cuò)循環(huán)地使用一組 N 個(gè)核心的處理器,或任何東西馍乙。在該限制下布近, 一個(gè)簡單、非并行丝格、逐項(xiàng)的惰性實(shí)現(xiàn)就在 sepc 之中了撑瞧,但是不太可能高效的使用多核∠则颍‘
不考慮性能要求预伺,如果算法依賴于這些采用的方法, 那也是錯(cuò)誤的曼尊。
Reduction 操作符
任何中綴操作符(除了 non-associating 操作符)都可以在 term 位置處被方括號圍住酬诀, 以創(chuàng)建使用使用該操作符進(jìn)行換算的列表操作符:
[+] 1, 2, 3; # 1 + 2 + 3 = 6
my @a = (5,6);
[*] @a; # 5 * 6 = 30
對于所有的元操作符來說, 在 metatoken
里面是不允許有空格的.
換算操作符和列表前綴的優(yōu)先級相同。 實(shí)際上骆撇, 換算操作符就是一個(gè)列表前綴瞒御,被當(dāng)作一個(gè)操作符來調(diào)用。因此神郊, 你可以以兩種方式的任何一種來實(shí)現(xiàn)換算操作符葵腹。要么你也能寫一個(gè)顯式的列表操作符:
multi prefix:<[+]> (*@args) is default {
my $accum = 0;
while (@args) {
$accum += @args.shift();
}
return $accum;
}
或者你能讓系統(tǒng)根據(jù)對應(yīng)的中綴操作符為你自動生成一個(gè):
&prefix:<[*]> ::= &reduce.assuming(&infix:<*>, 1);
&prefix:<[**]> ::= &reducerev.assuming(&infix:<**>);
如果換算操作符和中綴操作符的定義是獨(dú)立的高每, 那換算操作符和該操作符的結(jié)合性要相同:
[-] 4, 3, 2; # 4-3-2 = (4-3)-2 = -1
[**] 4, 3, 2; # 4**3**2 = 4**(3**2) = 262144
對于 list-associative 操作符(優(yōu)先級表中的 X),實(shí)現(xiàn)必須把參數(shù)的 listiness 考慮在內(nèi)践宴; 即鲸匿,如果重復(fù)地應(yīng)用一個(gè)二元版本的操作符會產(chǎn)生錯(cuò)誤的結(jié)果,那么它就不會被那樣實(shí)現(xiàn)阻肩。 例如:
[^^] $a, $b, $c; # means ($a ^^ $b ^^ $c), NOT (($a ^^ $b) ^^ $c)
對于 chain-associative 操作符(像 <)带欢, 所有的參數(shù)被一塊兒接收, 就像你顯式地寫出:
[<] 1, 3, 5; # 1 < 3 < 5
對于列表中綴操作符烤惊, 輸入列表不會被展平乔煞, 以至于多個(gè) parcels 可以以逗號分割形式的參數(shù)傳遞進(jìn)來:
[X~] (1,2), <a b>; # 1,2 X~ <a b>
如果給定的參數(shù)少于 2 個(gè), 仍然會用給定的參數(shù)嘗試分派柒室, 并根據(jù)那個(gè)分派的接受者來處理少于 2 個(gè)參數(shù)的情況渡贾。 注意,默認(rèn)的列表操作符簽名是最通用的雄右, 所以空骚, 你被允許根據(jù)類型去定義不同的方式處理單個(gè)參數(shù)的情況:
multi prefix:<[foo]> (Int $x) { 42 }
multi prefix:<[foo]> (Str $x) { fail "Can't foo a single Str" }
然而, 0 參數(shù)的情況不能使用這種方式定義擂仍, 因?yàn)闆]有類型信息用于分派囤屹。操作符要想指定一個(gè)同一值應(yīng)該通過指定一個(gè)接收 0 個(gè)參數(shù)的 multi 變體來實(shí)現(xiàn)這:
multi prefix:<[foo]> () { 0 }
在內(nèi)建操作符中,舉個(gè)例子逢渔, [+]()
返回 0 肋坚, [*]()
返回 1 。
默認(rèn)地肃廓, 如果有一個(gè)參數(shù)智厌, 內(nèi)建的換算操作符就返回那個(gè)參數(shù)。 然而盲赊, 這種默認(rèn)對于像 <
那樣返回類型和接收參數(shù)不同的操作符沒有效果峦剔,所以這種類型的操作符重載了單個(gè)參數(shù)的情況來返回更有意義的東西。為了和鏈?zhǔn)秸Z義保持一致角钩, 所有的比較操作符都對于 1 個(gè)或 0 個(gè)參數(shù)返回 Bool::True。
你也可以搞一個(gè)逗號操作符的換算操作符呻澜。 這正是 circumfix:<[ ]>
匿名數(shù)組構(gòu)建器的列表操作符形式:
[1,2,3] # make new Array: 1,2,3
[,] 1,2,3 # 與上相同
內(nèi)置換算操作符返回下面的同一值:
[**]() # 1 (arguably nonsensical)
[*]() # 1
[/]() # fail (換算沒有意義)
[%]() # fail (換算沒有意義)
[x]() # fail (換算沒有意義)
[xx]() # fail (換算沒有意義)
[+&]() # -1 (from +^0, the 2's complement in arbitrary precision)
[+<]() # fail (換算沒有意義)
[+>]() # fail (換算沒有意義)
[~&]() # fail (sensical but 1's length indeterminate)
[~<]() # fail (換算沒有意義)
[~>]() # fail (換算沒有意義)
[+]() # 0
[-]() # 0
[~]() # ''
[+|]() # 0
[+^]() # 0
[~|]() # '' (length indeterminate but 0's default)
[~^]() # '' (length indeterminate but 0's default)
[&]() # all()
[|]() # any()
[^]() # one()
[!==]() # Bool::True (also for 1 arg)
[==]() # Bool::True (also for 1 arg)
[before]() # Bool::True (also for 1 arg)
[after]() # Bool::True (also for 1 arg)
[<]() # Bool::True (also for 1 arg)
[<=]() # Bool::True (also for 1 arg)
[>]() # Bool::True (also for 1 arg)
[>=]() # Bool::True (also for 1 arg)
[~~]() # Bool::True (also for 1 arg)
[!~~]() # Bool::True (also for 1 arg)
[eq]() # Bool::True (also for 1 arg)
[!eq]() # Bool::True (also for 1 arg)
[lt]() # Bool::True (also for 1 arg)
[le]() # Bool::True (also for 1 arg)
[gt]() # Bool::True (also for 1 arg)
[ge]() # Bool::True (also for 1 arg)
[=:=]() # Bool::True (also for 1 arg)
[!=:=]() # Bool::True (also for 1 arg)
[===]() # Bool::True (also for 1 arg)
[!===]() # Bool::True (also for 1 arg)
[eqv]() # Bool::True (also for 1 arg)
[!eqv]() # Bool::True (also for 1 arg)
[&&]() # Bool::True
[||]() # Bool::False
[^^]() # Bool::False
[//]() # Any
[min]() # +Inf
[max]() # -Inf
[=]() # Nil (same for all assignment operators)
[,]() # []
[Z]() # []
[=] $x, @y, $z, 0
[+=] $x, @y, $z, 1
等價(jià)于:
$x = @y[0] = @y[1] = @y[2] ... @y[*-1] = $z = 0
$x += @y[0] += @y[1] += @y[2] ... @y[*-1] += $z += 1
而不是:
$x = @y = $z = 0;
$x += @y += $z += 1;
my :($b, $c); # okay
sub foo :($a,$b) {...} # okay
->
"pointy block" token 也引入簽名, 但是這種情況你必須省略冒號和括號. 例如, 如果你在定義 loop block 的 "循環(huán)變量":
for @dogpound -> Dog $fido { ... }
$foo.bar.baz.bletch.whatever.attr[] = 1,2,3;
空的 [] 和 .[] 后綴操作符被解釋為 0 維下標(biāo), 這返回整個(gè)數(shù)組, 不是作為一個(gè)一維的空切片, 返回空元素. 這同樣適用于散列上的 {} 和 .{} , 還有 <>
, .<>
,??
, 和 .??
递礼。