Kai*_*epi 8 polymorphism types module raku
角色的一个特性是角色组,它允许你声明多个同名角色接受不同的参数,类似于多例程:
role Foo[Int:D] {
method is-int(::?CLASS:_: --> True) { }
method is-str(::?CLASS:_: --> False) { }
}
role Foo[Str:D] {
method is-int(::?CLASS:_: --> False) { }
method is-str(::?CLASS:_: --> True) { }
}
Run Code Online (Sandbox Code Playgroud)
通常,对于一种类型,您有一个模块。问题是unit一个模块中只能有一个作用域声明,因此不能将它与角色组一起使用。如何为角色组编写模块?
您可以unit在其中包含没有作用域声明的模块并从中导出符号,但是如何导出角色组有点问题。您不能is export为此使用trait,因为这会导出错误的类型。当您在声明后引用角色时,您指的是角色组,而不是其中的单个角色,但是is export在单个角色上使用将导出这些单个角色,而不是角色的组。单个角色与角色组有非常不同的 HOW,并且不会像您通常期望的角色那样行事!
幸运的是,有一种方法可以使用EXPORT包来做到这一点。Foo在这个包中声明角色组会给它一个EXPORT::DEFAULT::Foo你可能不想要的名称,所以你需要MY在单元的范围内声明它并为它声明一个常量EXPORT::DEFAULT:
use v6.d;
my role Foo[Int:D] {
method is-int(::?CLASS:_: --> True) { }
method is-str(::?CLASS:_: --> False) { }
}
my role Foo[Str:D] {
method is-int(::?CLASS:_: --> False) { }
method is-str(::?CLASS:_: --> True) { }
}
my package EXPORT::DEFAULT {
constant Foo = ::Foo;
}
Run Code Online (Sandbox Code Playgroud)
现在Foo可以导入使用OK了:
use Foo;
say ::<Foo>:exists; # OUTPUT: True
say try Foo[1].is-int; # OUTPUT: True
say try Foo['ok'].is-str; # OUTPUT: True
Run Code Online (Sandbox Code Playgroud)
注意:您不能::在常量名称中使用,因此要在命名空间中导出角色组,您需要将其包装在另一个包中:
my role Foo::Bar[Int:D] { }
my role Foo::Bar[Str:D] { }
my package EXPORT::DEFAULT {
package Foo {
constant Bar = Foo::Bar;
}
}
Run Code Online (Sandbox Code Playgroud)