簡體   English   中英

Raku 簽名 (Array @r) 不是 (Array:D)?

[英]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

所以...這是我的評論:

  • 你非常接近(!)
  • @lizmat 對dd的指導對我很有幫助
  • 除非你想要一個驚喜,否則使用@作為@lists的標志
  • 除非你真的需要rule ,否則只使用token
  • types 非常適合檢查和 multis ...
  • Int @array意味着捕獲將檢查例如my Int @array = [1,2,3]這(如 lizmat 所說)與具有 Int 值[1,2,3]的數組不同(這里是類型檢查是委托控制分配給數組的內容)
  • 不需要像%$這樣的 perl 樣式 derefs
  • <key>{'key'}相同但輸入更少
  • 比賽 object 非常復雜和強大...... dd 顯示了內部結構,但這通常是矯枉過正
  • 使用say並將匹配字符串化為"" (或.Str )以獲得您真正需要的東西
  • use Grammar::Tracer; 你是朋友嗎

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM