首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用类型强制进行绑定

使用类型强制进行绑定
EN

Stack Overflow用户
提问于 2020-07-19 19:09:12
回答 1查看 79关注 0票数 3

我正在尝试在签名中使用类型强制。

如何修复my Chars(Str) @a := 'hello';行才能使这段代码正常工作?

代码语言:javascript
复制
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;
EN

回答 1

Stack Overflow用户

发布于 2020-07-20 09:00:34

你还没有说出你想要做的实际事情,所以这个答案试图从字里行间读出。幸运的是,它可以接近你想要的,或者至少是教育意义上的,或者是几英里之外的。无论哪种方式,如果你通过评论和/或编辑你的答案来回应这个答案,我可能会让它变得更有用。

我对你所追求的东西的最好的猜测

以下内容看起来工作正常,但没有任何保证:

代码语言:javascript
复制
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。如果你把它改回来并运行我的代码,你就会明白为什么。

  • 类型检查错误消息很奇怪:"in assignment to;“。

  • my @a is Chars是到符号@a.

的新Chars和相应类型约束的永久和编译时绑定

从字面上回答你的问题

具有类型强制的

绑定

my (Chars(Str) $a) := '1';说$a.WHAT;# (Chars)

我正在尝试在签名中使用类型强制。

使用signature这个词可以表示:

代码语言:javascript
复制
sub a (Chars(Str) $a) { $a }
say WHAT a '1'; # (Chars)

或者,不太可能:

代码语言:javascript
复制
my Chars $a;
:(Chars(Str) $a) := \'hello';

语法:(...)指定了一个独立的签名。它们很少使用,而且有点奇怪。例如,如果绑定到一个独立的签名,那么其中的任何变量都必须存在于绑定发生的直接词法作用域中。就像例程签名一样,它们被绑定到Capture。与调用例程时发生的例程签名绑定不同,编译器不会为您将:=绑定的RHS (相当于例程的参数)转换为Capture,因此您必须这样做,例如使用\捕获操作符。

但我强烈怀疑这是你要找的。

如果你真的对在例程之外声明一个变量感兴趣,那么可以使用列表声明语法(即使你只绑定到一个变量):

代码语言:javascript
复制
my (Chars(Str) $a) := \'hello';

额外的花括号起到了作用。但您仍然必须使用绑定和捕获。

而且,奇怪的是(或者我只是太困了?),如果你尝试赋值,强制不会发生:

代码语言:javascript
复制
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]],一个由单字符元素组成的数组。我很确定你不是这个意思。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62979456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档