Cách tạo một Capture động (Raku)


8

Trong ví dụ sau, tôi cố gắng tạo một Capture một cách linh hoạt bằng cách "chuyển đổi" một mảng (@a) thành một Capture.

Hãy xem xét mã:

sub f (|c){
    say '';
    say '  List : ' ~ do {c.list.gist if c.list.elems > 0};
    say '  Hash : ' ~ do {c.hash.gist if c.hash.elems > 0};
    say '';
}

my $c1 = \(1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9);

my @a  =   1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9;
my $c2 = \(|@a);

f(|$c1);

f(|@a);
f(|$c2);

Kết quả là:

  List : (1 (2 3) 4 5 6 7 8 9)
  Hash : Map.new((t1 => test1, t2 => test2))


  List : (1 (2 3) 4 5 t1 => test1 6 7 t2 => test2 8 9)
  Hash : 


  List : (1 (2 3) 4 5 t1 => test1 6 7 t2 => test2 8 9)
  Hash : 

Lần chạy đầu tiên (với Capture $ c1) đang chạy như bình thường, tạo ra hành vi mong muốn. Các nỗ lực thứ hai và thứ ba, để tạo một Capture một cách linh hoạt, đều thất bại (có thể là do đối số của chương trình con f trong các trường hợp đó KHÔNG phải là Capture mong muốn). Tôi quan sát rằng các cặp được kết hợp vào mảng @a, được coi là thành viên của danh sách và KHÔNG được đặt tên tham số như tôi muốn.

Tôi biết rằng phải có, nói, "làm phẳng" các cặp trong mảng đang diễn ra, trước khi chuyển sang chương trình con f, nhưng tôi KHÔNG thể tìm ra cách để làm điều đó!

Bất cứ ai có thể cho tôi một gợi ý?

Câu trả lời:


7

Trong lớp Listcó phương thức Capture, hoạt động chính xác như bạn muốn:

my $c  = \(1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9);
my @a  =   1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9;
my $c2 = @a.Capture;
f(|$c);
f(|$c2);
f(|@a);
sub f (|c){
    say() ;
    say '  List : ', c.List;
    say '  Hash : ', c.Hash;
    say();
}

Bạn có thể sửa đổi định nghĩa của hàm fđể làm việc trực tiếp với danh sách @a.

my $c  = \(1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9);
my @a  =   1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9;
f($c);
f(@a);
sub f (Capture(Any) \c){
    say() ;
    say '  List : ', c.List;
    say '  Hash : ', c.Hash;
    say();
}

Capture(Any)được gọi là loại cưỡng chế . Nó chấp nhận Anynhưng ép buộc Capture, tức là nó (lặp đi lặp lại) gọi phương thức Captuređể có được nó.

Ngoài ra, bằng cách Capturebạn có thể sử dụng khớp mẫu. Do đó, định nghĩa cuối cùng của hàm fcó thể được thay đổi thành:

sub f ( (**@list, *%hash) ) {
#or even sub f ( (*@list, :t1($t),*%hash) ) {
    say() ;
    say '  List : ', @list;
    # say ' test1 : ', $t;
    say '  Hash : ', %hash;
    say();
}  

Bạn có thể giải thích thêm một chút tại sao giải pháp thứ hai của bạn hoạt động?
Jakar

1
Tôi đã thêm lời giải thích vào cuối câu trả lời của tôi.
wamba

Nếu bạn đang sử dụng Foo(Any)như một loại, có lẽ bạn chỉ có thể sử dụng Foo(). Tôi không thể tưởng tượng được một thời gian khi bạn tham gia Anynhưng không phải làAny Mu
dùng0721090601
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.