我正在尝试在签名中使用类型强制。
如何修复my Chars(Str) @a := 'hello';行才能使这段代码正常工作?
class Chars is Array {
submethod new(Str:D $s) {
nextwith(|$s.comb);
}
}
use MONKEY-TYPING;
augment class Str {
method Chars { Chars.new(self) }
}
say Chars.new("hello").raku;
say "hello".Chars.raku;
my Chars(Str) @a := 'hello';
@a.raku.say;发布于 2020-07-20 09:00:34
你还没有说出你想要做的实际事情,所以这个答案试图从字里行间读出。幸运的是,它可以接近你想要的,或者至少是教育意义上的,或者是几英里之外的。无论哪种方式,如果你通过评论和/或编辑你的答案来回应这个答案,我可能会让它变得更有用。
我对你所追求的东西的最好的猜测
以下内容看起来工作正常,但没有任何保证:
subset Char of Str where .chars <= 1;
say Char ~~ Str; # True
class Chars is Array[Char] { multi method new (Str:D $_) { samewith |.comb } }
my @a is Chars;
say @a.WHAT; # Chars
@a = Chars.new: 'foo';
say @a; # [f o o]
say @a.elems; # 3
say @a.of; # Char
@a = 'buzz'.comb;
say @a; # [b u z z]
say @a.elems; # 4
@a = '4', '2';
say @a; # [4 2]
@a[3] := '9';
say @a; # [4 2 (Char) 9]
@a[4] = '100'; # Type check failed in assignment to ;
# expected Char but got Str ("100")
use MONKEY-TYPING;
augment class Str { method Chars { Chars.new: self } }
my (Chars(Str) $a) := \'hello';
say WHAT $a; # Str
say $a; # [h e l l o]
$a[1..3] = 'bar'.comb;
say $a; # [h b a r o]Char子集来对应单个字符串类型的约束,并在is Array[Char]中声明/定义Chars类时使用了该约束。samewith,不是nextwith。如果你把它改回来并运行我的代码,你就会明白为什么。my @a is Chars是到符号@a.的新Chars和相应类型约束的永久和编译时绑定
从字面上回答你的问题
具有类型强制的
绑定
my (Chars(Str) $a) := '1';说$a.WHAT;# (Chars)
我正在尝试在签名中使用类型强制。
使用signature这个词可以表示:
sub a (Chars(Str) $a) { $a }
say WHAT a '1'; # (Chars)或者,不太可能:
my Chars $a;
:(Chars(Str) $a) := \'hello';语法:(...)指定了一个独立的签名。它们很少使用,而且有点奇怪。例如,如果绑定到一个独立的签名,那么其中的任何变量都必须存在于绑定发生的直接词法作用域中。就像例程签名一样,它们被绑定到Capture。与调用例程时发生的例程签名绑定不同,编译器不会为您将:=绑定的RHS (相当于例程的参数)转换为Capture,因此您必须这样做,例如使用\捕获操作符。
但我强烈怀疑这是你要找的。
如果你真的对在例程之外声明一个变量感兴趣,那么可以使用列表声明语法(即使你只绑定到一个变量):
my (Chars(Str) $a) := \'hello';额外的花括号起到了作用。但您仍然必须使用绑定和捕获。
而且,奇怪的是(或者我只是太困了?),如果你尝试赋值,强制不会发生:
my (Chars(Str) $a) = \'hello';
say WHAT $a; # Str如何修复
my Chars(Str) @a := 'hello';?
如果你尝试一下,你会看到一条错误消息,比如:Coercion Foo(Bar) is insufficiently type-like to qualify a variable。
如果绑定到签名,则必须绑定Capture。
您正在声明一个带有@符号的变量。这意味着它左边的类型约束约束变量的元素,而不是整个变量本身。也就是说,像my Chars @a;这样的声明声明了一个Array[Chars]。根据我上面的代码,这将是一个Array[Array[Char]],一个由单字符元素组成的数组。我很确定你不是这个意思。
https://stackoverflow.com/questions/62979456
复制相似问题