在 Raku 术语中,属性是指每个实例/对象存储槽。Attribute
用于在元级别讨论类和角色的属性。
正常使用属性不需要用户显式使用此类。
特征§
特征是默认的§
分配了Nil
的属性将恢复为使用特征is default
设置的默认值。对于数组或关联数组,is default
的参数将设置默认项值或哈希值。
my = C.new;say ;.a = Nil;say ;# OUTPUT: «C.new(a => 666)C.new(a => 42)»;my = Foo.new( bar => <a b c> );.bar =Nil;say ; # OUTPUT: «Foo.new(bar => [42])»
特征是必需的§
multi trait_mod:<is> (Attribute , :!)
特征is required
将标记属性,以便在实例化对象时用值填充它。如果不这样做,将导致运行时错误。
my = C.new;CATCH# OUTPUT: «X::Attribute::Required: The attribute '$!a' is required, but you did not provide a value for it.»
此特征还允许使用具有:D
笑脸的类型对属性进行类型化,而无需为其提供默认值
从 6.d 语言版本开始可用(早期实现存在于 Rakudo 编译器 2018.08+ 中):您可以指定属性必需的原因
my = D.new;CATCH# OUTPUT: «X::Attribute::Required: The attribute '$!a' is required because it is a good idea,but you did not provide a value for it.»
is required
不仅影响默认构造函数,它还检查较低级别的属性,因此它将适用于使用bless编写的自定义构造函数。
特征已弃用§
multi trait_mod:<is>(Attribute , :!)
将属性标记为已弃用,可以选择使用消息来代替。
my = C.new( foo => 42 ); # doesn't trigger with initialization (yet)say .foo; # does trigger on usage
在程序完成后,这将在 STDERR 上显示类似这样的内容
# Saw 1 occurrence of deprecated code.# =====================================# Method foo (from C) seen at:# script.raku, line 5# Please use 'bar' instead.
特征是可读写的§
multi trait_mod:<is> (Attribute , :!)
将属性标记为可读写,而不是默认的readonly
。属性的默认访问器将返回可写值。
;my = Boo.new;.bar = 42; # works.baz = 42;CATCH ;# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Any»
特征已构建§
multi trait_mod:<is>(Attribute , :!)
默认情况下,此特性允许通过 .new
在对象构造期间设置一个私有属性。通过传递布尔值 False
,可以使用相同的特性来阻止通过 .new
设置公有属性。
my = Foo.new(bar => 1, baz => 2);say .bar; # OUTPUT: «1»say .baz; # OUTPUT: «Any»
在 Rakudo 编译器的 2020.01 版本中可用。
方法§
获取 Attribute
类型对象的通常方法是内省
my = Useless.^attributes(:local)[0];say .raku; # OUTPUT: «Attribute.new»say .name; # OUTPUT: «@!things»say .package; # OUTPUT: «(Useless)»say .has_accessor; # OUTPUT: «False»
通常无法从外部修改私有属性,但由于 Attribute 处于元类的级别,所以一切都公平公正。
方法名称§
method name(Attribute: --> Str)
返回属性的名称。请注意,这始终是私有名称,因此如果将属性声明为 has $.a
,则返回的名称为 $!a
。
my = Foo.^attributes(:local)[0];say .name; # OUTPUT: «@!bar»
方法包§
method package()
返回此属性所属的包(类/语法/角色)。
my = Boo.^attributes(:local)[0];say .package; # OUTPUT: «(Boo)»
方法 has_accessor§
method has_accessor(Attribute: --> Bool)
如果属性具有公有访问器方法,则返回 True
。
my = Container.^attributes(:local)[0];my = Container.^attributes(:local)[1];say .has_accessor; # OUTPUT: «False»say .has_accessor; # OUTPUT: «True»
方法 rw§
method rw(Attribute: --> Bool)
对于应用了“is rw”特性的属性,返回 True
。
my = Library.^attributes(:local)[0];my = Library.^attributes(:local)[1];say .rw; # OUTPUT: «False»say .rw; # OUTPUT: «True»
方法 readonly§
method readonly(Attribute: --> Bool)
对于只读属性(这是默认值)返回 True
,或者对于标记为 is rw
的属性返回 False
。
my = Library.^attributes(:local)[0];my = Library.^attributes(:local)[1];say .readonly; # OUTPUT: «True»say .readonly; # OUTPUT: «False»
方法 required§
method required(Attribute: --> Any)
对于应用了“is required”特性的属性,返回 1
,或者如果属性没有应用该特性,则返回 Mu
。如果“is required”特性应用于一个字符串,则会返回该字符串而不是 1
。
my = Library.^attributes(:local)[0];my = Library.^attributes(:local)[1];say .required; # OUTPUT: «1»say .readonly; # OUTPUT: «"we always need more books"»
方法类型§
method type(Attribute: --> Mu)
返回属性的类型约束。
my = TypeHouse.^attributes(:local)[0..2];for 0..2# OUTPUT: «(Positional[Int])# (Mu)# (Positional)»
方法 get_value§
method get_value(Mu )
返回存储在对象 $obj
的此属性中的值。
my = Violated.^attributes(:local)[0];say .get_value(Violated.new); # OUTPUT: «5»
请注意,此方法违反了对象的封装,应谨慎使用。此地有龙。
方法 set_value§
method set_value(Mu , Mu \new_val)
将值 new_val
绑定到对象 $obj
的此属性。
my = A.^attributes(:local)[0];my = A.new;.speak; # OUTPUT: «5».set_value(, 42);.speak; # OUTPUT: «42»
请注意,此方法违反了对象的封装,应谨慎使用。此地有龙。
方法 gist§
multi method gist(Attribute:)
返回类型名称后跟属性名称。
say Hero.^attributes(:local)[0]; # OUTPUT: «Positional @!inventory»
由于 say 隐式调用 .gist
,因此这里会产生输出。
可选内省§
已弃用§
如果某个属性标记为 DEPRECATED
,则可以调用 DEPRECATED
方法,它将返回 "something else"
(如果未指定具体原因)或使用 DEPRECATED
特征指定的字符串。
如果某个属性未标记为 DEPRECATED,则不能调用 DEPRECATED
方法。因此,应使用 .?method
语法。
my = Hangout.^attributes(:local)[0];my = Hangout.^attributes(:local)[1];with .?DEPRECATED ->with .?DEPRECATED ->