当前位置: 首页 > 知识库问答 >
问题:

perl6/raku:如何限制变量中允许的值?

空俊语
2023-03-14

Perl6/Raku

我想创建一个sub,因为只允许将某些值传递给它。不传递允许的值将创建一个checker错误(perl6-c)。

我该怎么做?

非常感谢,-T

你好,Raiph,

在我的WinPopUps模块中,我使用了“在哪里”方法,因为它一目了然地告诉用户允许的值是什么。我喜欢它!这一切都是关于可运维性的!(顺便说一句,下面是你创建的怪物!)

sub WinPopUp( Str $TitleStr, 
              Str $MessageStr,
              Str $Icons where   * ~~ "Exclamation"             |
                                      "Warning"                 |
                                      "Information"             |
                                      "Asterisk"                |
                                      "Question"                |
                                      "Stop"                    |
                                      "Error"                   |
                                      "Hand",
              Str $Buttons where * ~~ "AbortRetryIgnore"        | 
                                      "CancelTryAgainContinue"  |
                                      "Help"                    |
                                      "Ok"                      |
                                      "OkCancel"                |
                                      "RetryCancel"             |
                                      "YesNo"                   |
                                      "YesNoCancel" ) 
              is export( :WinPopUp ) {

谢谢你的帮助-T

如果您想要完整的模块以及在哪里发布,请告诉我

共有2个答案

太叔小云
2023-03-14

在您的情况下,最好使用枚举:

enum Icons <Exclamation Warning Information>;
sub pop-up( Icons $icon ) { $icon}; 
say pop-up( Information ); # OUTPUT: «Information␤»

但是,由于某种原因,您已经在使用Str,因此使用子集可能更好:

subset Icons of Str where * eq any <Exclamation Warning Information>;
sub pop-up( Icons $icon ) { $icon};
say pop-up( "Information" ); 

这些已经在Holli的回答中提到了,尽管只是“如果你要多次使用它们”。我会定义一个子集,即使你只使用它一个。它更安全,也更清晰,并且可测试。

邵阳辉
2023-03-14

您可以简单地在值上添加在哪里条件

sub foo( Int $binary where * ~~ 0|1 ) { ... }

在哪里条件可以是任意代码块(甚至是我相信的子代码块)。

如果多次需要该条件,可以创建子集。

subset BinaryInt of Int where * ~~ 0|1;

然后在签名中使用它

sub foo( BinaryInt $binary ) { ... }

请注意,这不仅仅限于子程序签名。约束/条件在任何地方都被强制执行

my BinaryInt $i = 0; 
$i++; 
$i++;
# -> Type check failed in assignment to $i; expected BinaryInt but got Int (2)

您还可以拥有子集的子集:

subset FalseBinaryInt of BinaryInt where not *;
my FalseBinaryInt $i = 0; 
$i++; 
# -> Type check failed in assignment to $i; expected FalseBinaryInt but got Int (1)

编辑:下面的JJ是对的。在这种情况下,枚举很有用。这

sub WinPopUp( Str $TitleStr, 
              Str $MessageStr,
              MessageBoxIcons $Icons where   * ~~ Exclamation |
                                                  Information |
              ...

与类似的枚举配对

enum MessageBoxIcons is export {
    Exclamation => 0x00000030,
    Information => 0x00000040,
    ...
}

保护您免受随机输入错误的影响,因为枚举成员是符号,如果您错拼了一个,编译器将捕获它。此外,您不必查找要输入到MessageBoxW的值(我假设您正在这样做)。

说到MessageBoxW,我会称您的子消息框(在Raku中,我们倾向于仅将CamelCase用于类和类型等)只是为了与MessageBoxW保持一致

 类似资料:
  • 问题内容: 说,我有如下通用类型 我想让它只接受特定的类型(字符串/整数/双精度)。我知道有界通配符,但在这里对我没有帮助。在setVar()中,如果类型不是Integer / String等,我可以检查并引发异常。这是最好的方法吗? 在对此类型进行操作时,我遇到同样的问题。根据类型,我想执行不同的操作。继承和有界通配符似乎通常是解决此类问题的方法,但它们是原始包装器。 问题答案: 使用继承: P

  • 我知道围棋习语没有setter和getter。但我需要限制Go中变量的值。 我定义了新类型 被定义为MyStringType的变量需要限制值。 MyStringType的变量只能有3个值:“是”、“否”、“我不知道” 如何在戈朗中做到这一点?在Java中,C中有setter和getter,但在Golang中是不正常的。 我知道,我可以创造 并创造 但我认为这是错误的方式。

  • 问题内容: 我上课了。我怎么能说我想成为某个班级的实施者?编写根本无法编译。 问题答案: 使用代替。

  • 我试图在我的汇总配置中设置一个SASS结构,允许我在整个应用程序中使用变量。我想用POSTSS自动刷新器。我在插件阵列中设置了以下内容: 这很好,我可以在我的组件中导入我的SCSS文件,比如,

  • 我正在创建一个程序来提示用户输入信息,所以我创建了多个变量,然后让程序根据这些变量输出信息。出于某种原因,每当我声明新的年龄变量时,程序都会给我一个奇怪的错误,在线程“main”中说Exception。我试着将第一次扫描关闭到,但不起作用。 我的密码是

  • 我有两个域名。 我尝试使用JavaScript标记,在用户对域2进行一些操作之后,使用一切正常,但在最后一步,我得到了跨原点错误。 如何在PHP中允许访问域1上的跨源? 编辑 我的问题不是这个问题的可能重复,因为我问的是PHP。 解决方案 只需在打开PHP标签后的代码开头添加,这将允许从任何来源(网站)进行访问。 如果要限制访问,请将替换为源站(网站)url,如