[英]Raku signature (Array @r) is not (Array:D)?
我似乎無法理解我在探索語法時發現的這條 Raku 錯誤信息……
Cannot resolve caller report(Array:D); none of these signatures matches:
(Array @r)
(Match $r)
所以數組不是數組?? 這是如何工作的,我如何找出原因。 這是完整的程序和輸出。
#!/usr/bin/env perl6
use v6;
grammar Integers {
rule TOP { ^ .*? <targets> .* $ }
rule targets { <integer>+ % ',' }
token integer { \d+ }
}
multi sub report(Array @r) { say @r.raku }
multi sub report(Match $r) { say $r.raku }
sub MAIN() {
my $result = Integers.parse(' a 1234 ');
report($result);
report(%$result{'targets'});
report(%$result{'targets'}{'integer'});
}
#`( output:
Match.new(:orig(" a 1234 "), :from(0), :pos(8), :hash(Map.new((:targets(Match.new(:orig(" a 1234 "), :from(3), :pos(8), :hash(Map.new((:integer([Match.new(:orig(" a 1234 "), :from(3), :pos(7))]))))))))))
Match.new(:orig(" a 1234 "), :from(3), :pos(8), :hash(Map.new((:integer([Match.new(:orig(" a 1234 "), :from(3), :pos(7))])))))
Cannot resolve caller report(Array:D); none of these signatures matches:
(Array @r)
(Match $r)
in sub MAIN at /home/hans/Programming/Raku/Parsing/Array_Array.raku line 16
in block <unit> at /home/hans/Programming/Raku/Parsing/Array_Array.raku line 3
)
您似乎對印記和打字的功能感到困惑。
當你使用@
sigil 時,你暗示了一個Positional
約束。
sub foo(@a) { ... }
將采取任何擔任Positional
角色的事情。
foo( @b );
foo( [1,2,3] );
foo( (1,2,3) );
當您在簽名中指定帶有@
的類型時,表示您想要一個只接受該類型作為其元素的Positional
。 現在,作為子例程的參數,這嚴重限制了您可以指定的內容,因為[1,2,3]
不是對Int
有約束的數組,它是一個恰好只填充Int
值的數組。
現在回到您的示例: (Array @r)
是什么意思? 這意味着您需要一個約束Array
對象的Positional
。 簡單來說:您想要一個必須包含 arrays 作為其元素的數組。
我不認為那是你想要的?
現在,為什么(Array $r)
有效? 因為這表明您需要一個Array
object 作為參數。 這也限制了你想要的,因為它必須是一個Array
,並且不能是一個List
例如。
sub foo(Array $r) { ... }
foo(@a); # works
foo( [1,2,3] ); # works
foo( (1,2,3) ); # does *not* work
最后,我認為您想使用內置的dd
而不是構建您自己的report
function。
好吧,我對自己的問題有部分答案。 如果我將 (Array @r) 更改為 (Array $r) 或者我只是刪除 Array 並使用 (@r)。
根據docs.raku.org “如果用戶沒有提供類型,Raku 假定類型為 Any”。 所以這解釋了為什么 (@r) 有效。 它只是(任何@r)......我想。
至於為什么 (Array:D) 必須編碼為 (Array $r),我還在想辦法解決這個問題。 越來越好奇。
嗨@FyFAIR,歡迎來到 raku。 IMO raku 是一個很棒的工具,但幾乎沒有護欄。 所以請耐心等待,因為當它點擊時,這是值得的;-)
我冒昧地按照我的方式重新起草了你的例子:
grammar Integers {
token TOP { ^ .*? <targets> .* $ }
token targets { <integer>+ % ',' }
token integer { \d+ }
}
sub MAIN() {
my $result = Integers.parse(' a 1234 ');
dd $result;
dd $result<targets>;
dd $result<targets><integer>; #<== a list of matches with one element
dd $result<targets><integer>[0];
say "$result<targets><integer>[0]";
}
Integers $result = Match.new(:orig(" a 1234 "), :from(0), :pos(8), :hash(Map.new((:targets(Match.new(:orig(" a 1234 "), :from(3), :pos(7), :hash(Map.new((:integer([Match.new(:orig(" a 1234 "), :from(3), :pos(7))]))))))))))
Match.new(:orig(" a 1234 "), :from(3), :pos(7), :hash(Map.new((:integer([Match.new(:orig(" a 1234 "), :from(3), :pos(7))])))))
[Match.new(:orig(" a 1234 "), :from(3), :pos(7))]
Match.new(:orig(" a 1234 "), :from(3), :pos(7))
1234
所以...這是我的評論:
dd
的指導對我很有幫助@
作為@lists的標志rule
,否則只使用token
Int @array
意味着捕獲將檢查例如my Int @array = [1,2,3]
這(如 lizmat 所說)與具有 Int 值[1,2,3]
的數組不同(這里是類型檢查是委托控制分配給數組的內容)%$
這樣的 perl 樣式 derefs<key>
與{'key'}
相同但輸入更少say
並將匹配字符串化為""
(或.Str
)以獲得您真正需要的東西use Grammar::Tracer;
你是朋友嗎
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.