我正在尝试在签名中使用类型强制。
如何修复该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;
Run Code Online (Sandbox Code Playgroud)
你还没有说你要做什么作为一个实际问题,所以这个答案试图在字里行间阅读。幸运的是,它可能接近你想要的,或者至少是教育性的,或者离你很远。无论哪种方式,如果您通过评论和/或编辑您的答案来回应此答案,我可能会使其更有用。
以下似乎工作正常,但不暗示保证:
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]
Run Code Online (Sandbox Code Playgroud)
我引入了一个Char 子集来对应单个字符串类型约束,并在is Array[Char]声明/定义Chars 类时使用该约束。
我用过samewith,没有nextwith。如果你把它改回来并运行我的代码,你就会明白为什么。
类型检查错误消息很奇怪:“分配给;”。
my @a is Chars是new和相应类型约束到符号的永久和编译时绑定。Chars @a
类型强制绑定
我的 (Chars(Str) $a) := '1'; 说 $a.WHAT; #(字符)
我正在尝试在签名中使用类型强制。
使用签名一词表明:
sub a (Chars(Str) $a) { $a }
say WHAT a '1'; # (Chars)
Run Code Online (Sandbox Code Playgroud)
或者,不太可能:
my Chars $a;
:(Chars(Str) $a) := \'hello';
Run Code Online (Sandbox Code Playgroud)
语法:(...)指定了一个独立的签名。它们很少使用,有点奇怪。例如,如果您绑定到一个独立的签名,那么其中的任何变量都必须存在于绑定发生的直接词法范围内。就像常规签名一样,它们绑定到Capture. 与调用例程时发生的例程签名绑定不同,编译器不会将:=绑定的 RHS (相当于例程的参数)转换为Capture适合您的,因此您必须这样做,例如通过使用\捕获运算符。
但我强烈怀疑这就是你所追求的。
如果您真的有兴趣在例程之外声明一个变量,那么可以使用列表声明语法(即使您只绑定到一个变量):
my (Chars(Str) $a) := \'hello';
Run Code Online (Sandbox Code Playgroud)
额外的括号会有所不同。但是您仍然必须使用绑定和捕获。
而且,奇怪的是(或者我只是太困了?),如果您尝试分配,则不会发生强制:
my (Chars(Str) $a) = \'hello';
say WHAT $a; # Str
Run Code Online (Sandbox Code Playgroud)
我该如何解决
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]]由单个字符元素组成的数组。我很确定你不是那个意思。
| 归档时间: |
|
| 查看次数: |
76 次 |
| 最近记录: |