在Moose中是否有某种方式指定我希望某个属性具有特定类型,但也允许存在空值(undef?)。
例如,我正在编写一个链接列表的简单实现,并且有一个Node类,其中next
和prev
指针必须是Node
类型(这可能是什么你会期待的)
package Node;
{
use Moose;
has 'value' => (
is => 'rw',
isa => 'Any', # Nodes can be of any type
);
has 'prev' => (
is => 'rw',
isa => 'Node',
predicate => 'has_prev',
);
has 'next' => (
is => 'rw',
isa => 'Node',
predicate => 'has_next',
);
}
但是我希望使用存储在列表头部的标记空节点来标记头部,而不是列表的实际元素。所以元素列表[1,2,3]实际上看起来像是:
EMPTY -> 1 -> 2 -> 3
我希望能够为next
和prev
指针指定一个空值(例如undef),但是当我在List类中创建一个空Node
时:< / p>
package List;
{
use Moose;
has 'head' => (
is => 'rw',
isa => 'Node',
# empty head node
default => sub {
Node->new( value => undef, next => undef, prev => undef );
},
);
Moose抱怨因为undef
不属于Node
类型。
有解决方法吗?
答案 0 :(得分:5)
您可以使用Maybe[type]
语法来允许类型或undef
。以你的例子:
has 'head' => (
is => 'rw',
isa => 'Maybe[Node]',
# empty head node
default => sub {
Node->new( value => undef, next => undef, prev => undef );
}
);
答案 1 :(得分:1)
下一个:
use 5.014;
use warnings;
package Node {
use Moose;
has 'value' => ( is => 'rw');
has 'prev' => ( is => 'rw', isa => 'Undef|Node', predicate => 'has_prev', default=>undef );
has 'next' => ( is => 'rw', isa => 'Undef|Node', predicate => 'has_next', default=>undef );
}
package List {
use Moose;
has 'head' => ( is => 'rw', isa => 'Node', default => sub { Node->new() } );
}
package main;
use Data::Dumper;
my $list = List->new();
say Dumper $list;
打印:
$VAR1 = bless( {
'head' => bless( {
'next' => undef,
'prev' => undef
}, 'Node' )
}, 'List' );
Moose::Manual::Types对于基本的hier说:
Undef <---- undefined Defined Value Str Num Int ClassName <---- Class name RoleName
以及后面的TYPE UNIONS部分说:
Moose允许您说某个属性可以是两个或更多 不同的类型。例如,我们可能允许使用Object或FileHandle:
有'output'=&gt; ( 是=&gt; 'RW', isa =&gt; '对象| FileHandle',);
正如其他人已经说过的,这里也是Maybe[Something]
,我不知道什么是更好的,但Something | SomethingOther
看起来更像“perlish”(恕我直言)。 ;)
答案 2 :(得分:0)
作者更喜欢Undef|Node
而不是Maybe[Node]
。
has 'prev' => (
is => 'rw',
isa => 'Undef|Node',
predicate => 'has_prev',
);