问题描述
在Raku中,HOW必须通过archetypes
方法公开原型列表,该方法用于确定类型实现的类型更广泛的功能,例如参数性或可组合性。我注意到metamodel::EnumHOW
(与枚举一起使用的操作方法)具有augmentable
原型,当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
在使用签名和参数功能方面相当费力。这取决于以下内容:
- 常量值可以像签名中的类型一样使用。其中包括枚举值,这些值在编译时进行处理。
- 通过使例程的签名的返回值类型成为常数,可以使例程始终返回恒定值。
- 签名中任何给定参数的变量都是可选的。
- 将冒号放在这样的第一个参数之后时,该第一个参数就是签名的 invocant 。对于方法,这使您可以根据需要键入
self
。 -
::?CLASS
是声明其方法的作用域的类的别名。它存在于类和角色主体中,因此尽管Foo
不是真正的类,但符号仍在引用到。 -
:D
是一种类型笑脸,表示类型应仅根据自己的实例进行类型检查,而不是像类型一样进行类型检查的对象。
由于foo
是比::?CLASS:D
(Foo:D
的别名)更具体的类型,因此在foo
上调用此方法时,foo
multi将选择True
将会被返回,但是在任何其他情况下,::?CLASS:D
都会被选择并返回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;