Traits
在 Raku 中,*traits*是附加到对象和类的编译器钩子,它们修改了类和对象的默认行为,功能或表示。作为这样的编译器钩子,它们是在编译时定义的,尽管它们可以用于运行时。
通过使用 trait_mod
关键字,已经将几个 traits 定义为语言或 Rakudo 编译器的一部分。接下来列出并解释它们。
is trait
定义为
proto sub trait_mod:<is>(Mu $, |) {*}
is
适用于任何类型的标量对象,并且可以接收任意数量的命名参数或位置参数。它是最常用的 trait,取决于第一个参数的类型,采用以下形式。
is
应用于类
最常见的形式涉及两个类,一个正在定义,另一个现有,定义为 defines parenthood。 A is B
, 如果两个都是类,则将 A 定义为 B 的子类。
is DEPRECATED
可以应用于类,属性或例程,将它们标记为已弃用并发出警告消息(如果提供了的话)。
is
的几个实例被直接转换为它们引用的类的属性:rw
,nativesize
,ctype
,unsigned
,hidden
,array_type
。
不可实例化的表示 trait 与表示没有多大关系,与特定类可以做什么有关; 它有效地防止以任何可能的方式创建类的实例。
constant @IMM = <Innie Minnie Moe>;
class don't-instantiate is repr('Uninstantiable') {
my $.counter;
method imm () {
return @IMM[ $.counter++ mod @IMM.elems ];
}
}
say don't-instantiate.imm for ^10;
不能实例化的类仍然可以通过它们的类变量和方法使用, 如上所示。尝试这样: my $do-instantiate = don’t-instantiate.new;
来实例化它们会产生错误。
is repr
和原生表示
由于 is
trait 通常指的是它们所应用的类或对象的性质,因此它们在link:(原生调用)中被广泛使用,以指定将由原生函数通过 is repr
后缀处理的数据结构的表示。同时,is native
用于通过原生函数实际实现的例程。这些是可以使用的表示:
CStruct 对应于 C 语言中的
struct
。它是一种复合数据结构,包括不同的异构和低级数据结构;请参阅此示例和进一步说明。类似地,CPPStruct 对应于 C++ 中的
struct
。但是,这是暂时是 Rakudo 特定的。CPointer 是任何这些语言的指针。它是一个动态数据结构,必须在使用之前进行实例化,可用于其方法也是原生的类。
CUnion 将使用与 C 中的
union
相同的表示形式; 看一下这个例子。
另一方面,P6opaque 是用于 Raku 中所有对象的默认表示。
class Thar {};
say Thar.REPR; #OUTPUT: «P6opaque
»
除非另有说明,否则元对象协议默认对每个对象和类使用它;因此,除非您有效地使用该接口,否则通常没有必要。
is
作用于例程
is
trait 可用于定义方法和例程以建立优先级和关联性。它们充当使用 trait_mod 定义的子元素,该元素将要添加的 trait 的类型和名称作为参数。在子例程的情况下,trait 将是添加跨越类和角色层次结构的功能的一种方式,或者甚至可以用于向独立定义的例程添加行为。