在 Rakudo 的更新版本中,有一个名为 UInt 的子集将其限制为正值。
class Wizard {
has UInt $.mana is rw;
}
这样,如果您需要这样的事情,您就不会陷入困境;这是如何定义的:
(您可以省略my,但我想向您展示来自Rakudo 源的actual line)
my subset UInt of Int where * >= 0;
你也可以这样做:
class Wizard {
has Int $.mana is rw where * >= 0;
}
我想指出where 约束中的* >= 0 只是创建Callable 的一种捷径。
您可以将以下任何一项作为where 约束:
... where &subroutine # a subroutine that returns a true value for positive values
... where { $_ >= 0 }
... where -> $a { $a >= 0 }
... where { $^a >= 0 }
... where $_ >= 0 # statements also work ( 「$_」 is set to the value it's testing )
(如果您希望它不为零,您也可以使用... where &prefix:<?>,它可能更好地拼写为... where ?* 或... where * !== 0)
如果您觉得让使用您的代码的人感到厌烦,您也可以这样做。
class Wizard {
has UInt $.mana is rw where Bool.pick; # accepts changes randomly
}
如果您想确保在查看类中所有值的总和时该值“有意义”,您将不得不做更多的工作。
(它可能还需要更多的实现知识)
class Wizard {
has Int $.mana; # use . instead of ! for better `.perl` representation
# overwrite the method the attribute declaration added
method mana () is rw {
Proxy.new(
FETCH => -> $ { $!mana },
STORE => -> $, Int $new {
die 'invalid mana' unless $new >= 0; # placeholder for a better error
$!mana = $new
}
)
}
}