enums - 枚举如何增强?

标签 enums metaprogramming raku

在 Raku 中,HOW 必须通过 archetypes 公开原型(prototype)列表。方法,用于确定类型实现的类型的哪些更广泛的特征,例如参数性或可组合性。我注意到 Metamodel::EnumHOW (与枚举一起使用的方式)具有 augmentable原型(prototype),用于在与 augment 组合后可以扩展的类型关键字当MONKEY-TYPING编译指示已启用。
我对枚举为什么可以增加的第一个猜测是允许添加枚举值,所以我试着写这个:

use v6;
use MONKEY-TYPING;

enum Foo <foo bar baz>;
augment enum Foo <qux>;
say qux;
但这会引发:
bastille% raku test.raku
===SORRY!=== Error while compiling /home/morfent/test.raku
Redeclaration of symbol 'Foo'.
at /home/morfent/test.raku:5
------> augment enum Foo⏏ <qux>;
因此,它们可能不打算以这种方式增强。
我的下一个猜测是,它们的目的是针对枚举值而不是枚举类型本身进行扩充。 augment ,有趣的是,当你告诉它你要增加什么样的类型时,并没有考虑到一个类型实际上有什么,所以我试着像增加一个类一样增加一个枚举:
use v6;
use MONKEY-TYPING;

enum Foo <foo bar baz>;

augment class Foo {
    proto method is-foo(::?CLASS:D: --> Bool:D) {*}
    multi method is-foo(foo: --> True)          { }
    multi method is-foo(::?CLASS:D: --> False)  { }
}

say foo.is-foo;
哪个有效:
bastille% raku test.raku
True
但这并不像是您打算如何为我增加枚举。 augment 的这种用法相当奇怪,并且没有任何暗示应该可以从其文档中做到这一点。你打算如何增加枚举?
常问问题
  • Foo.is-foo似乎没有任何代码?它在做什么?
  • is-foo对如何使用签名和参数的特性相当严厉。这取决于以下几点:
  • 常量值可以像签名中的类型一样使用。这包括在编译时处理的枚举值。
  • 通过将一个例程设为其签名的返回值的类型,可以使例程始终返回一个常量值。
  • 签名中任何给定参数的变量都是可选的。
  • 当像这样在第一个参数之后放置冒号时,第一个参数是签名的调用者。对于方法,这允许您输入 self随你怎么便。
  • ::?CLASS是在其范围内声明方法的类的别名。它存在于类和角色主体中,因此尽管 Foo不是一个真正的类(class),这就是这个符号所指的。
  • :D是一个类型笑脸,表示一个类型应该只对它自己的实例进行类型检查,而不是类型检查喜欢它的类型对象。

  • 由于foo是比 ::?CLASS:D 更具体的类型(Foo:D 的别名),当在 foo 上调用此方法时, foo multi 将被选中,True将被退回,但在任何其他情况下,::?CLASS:D multi 将被选中,False将被退回。

    最佳答案

    在 Java 中,您可以向枚举添加几乎任意的属性和函数。所以我确实认为你描述的方式增加是有道理的。例如:

    use MONKEY-TYPING;
    
    enum Days(Monday => 1, Tuesday => 2, Wednesday => 3, Thursday => 4, Friday => 5, Saturday => 6, Sunday => 7); 
    
    augment class Days {
        proto method is-weekend(::?CLASS:D: --> Bool:D) {*} 
        multi method is-weekend(Saturday: --> True)          { } 
        multi method is-weekend(Sunday: --> True) {}
        multi method is-weekend(::?CLASS:D: --> False)  { } 
    
        proto method days-til-weekend(::?CLASS:D: --> Int:D) {*}
        # there is probably a better way to express this, but
        # hopefully the concept is clear
        multi method days-til-weekend(Monday: --> 4) {}
        ...
    }
    
    say Monday.is-weekend;
    say Wednesday.days-til-weekend;
    say Saturday.is-weekend;
    

    关于enums - 枚举如何增强?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63942201/

    相关文章:

    c# - 我如何实现这个公共(public)可访问枚举

    Java Enum<T> 与 T 作为变量类型

    c++ - 模板意大利面

    Rakudo perl 6 便携版

    java - 为什么枚举上的开关需要默认值?

    delphi - 存储枚举的列表类?

    c++ - 部分专用类上的标记调度与静态方法

    c++ - 我可以在前向声明中默认模板参数吗

    raku - 使用Raku进行Web开发

    raku - Perl6 IO::Socket::Async 截断数据