如何将 class 属性声明为 class 名称的联合?
How do I declare a class attribute as a union of class names?
我正在阅读电子表格以寻找不同的结构。当我尝试使用 Moose 进行以下操作时,它似乎可以满足我的要求。我可以创建不同类型的对象,将其分配给找到的成员
并转储 Cell 实例以供审查。
package Cell
{
use Moose;
use Moose::Util::TypeConstraints;
use namespace::autoclean;
has 'str_val' => ( is => 'ro', isa => 'Str', required => 1 );
has 'x_id' => ( is => 'ro', isa => 'Str', ); # later required => 1 );
has 'color' => ( is => 'ro', isa => 'Str', );
has 'border' => ( is => 'ro', isa => 'Str', );
has 'found' => ( is => 'rw', isa => 'Sch_Symbol|Chip_Symbol|Net', );
1;
}
如果我尝试在 Perl 6 中做同样的事情,它会编译失败。
class Cell {
has Str $.str_val is required;
has Str $.x_id is required;
has Str $.color;
has Str $.border;
has Sch_Symbol|Chip_Symbol|Net $.found is rw
}
Malformed has
at C:\Users\Johan\Documents/moose_sch_3.pl6:38
------> has Sch_Symbol'<'HERE'>'|Chip_Symbol|Net $.found is rw
我如何在 Perl 6 中执行此操作?
您可能希望他们担任共同角色并将其指定为类型
role Common {}
class Sch-Symbol does Common {…}
…
class Cell {
…
has Common $.found is rw;
}
或者您将不得不使用 where
约束条件
class Cell {
…
has $.found is rw where Sch-Symbol|Chip-Symbol|Net;
}
您还可以创建一个子集来包装 where
约束。
subset Common of Any where Sch-Symbol|Chip-Symbol|Net;
class Cell {
…
has Common $.found is rw;
}
请注意,where
约束比使用普通角色慢。
你可以使用 where
has $.found is rw where Sch_Symbol|Chip_Symbol|Net;
或通过subset
定义新类型
subset Stuff where Sch_Symbol|Chip_Symbol|Net;
class Cell {
has Str $.str_val is required;
has Str $.x_id is required;
has Str $.color;
has Str $.border;
has Stuff $.found is rw;
}
这是 Brad Gilbert 在 中提到的 subset/where
解决方案的完整实施。这包括 Common
中每个 类 的一个示例,以及一个显示不满足类型约束时会发生什么的示例:
#!/bin/env perl6
class Sch-Symbol { has Str $.name }
class Chip-Symbol { has Num $.num }
class Net { has Int $.id }
subset Common of Any where Sch-Symbol|Chip-Symbol|Net;
class Cell {
has Str $.str_val is required;
has Str $.x_id is required;
has Str $.color;
has Str $.border;
has Common $.found is rw;
}
my $str_val = 'foo';
my $x_id = 'bar';
my @founds = (
Net.new(:42id), # will work
Sch-Symbol.new(:name<baz>), # will work
Chip-Symbol.new(num => 1E101), # will work
42, # won't work
);
for @founds -> $found {
my $cell = Cell.new(:$str_val, :$x_id, :$found);
dd $cell;
}
假设这在文件 test.p6
中,当我们 运行 perl6 test.p6
时我们得到:
Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Net.new(id => 42))
Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Sch-Symbol.new(name => "baz"))
Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Chip-Symbol.new(num => 1e+101))
Type check failed in assignment to $!found; expected Common but got Int (42)
in submethod BUILDALL at test.p6 line 9
in block <unit> at test.p6 line 28
我正在阅读电子表格以寻找不同的结构。当我尝试使用 Moose 进行以下操作时,它似乎可以满足我的要求。我可以创建不同类型的对象,将其分配给找到的成员 并转储 Cell 实例以供审查。
package Cell
{
use Moose;
use Moose::Util::TypeConstraints;
use namespace::autoclean;
has 'str_val' => ( is => 'ro', isa => 'Str', required => 1 );
has 'x_id' => ( is => 'ro', isa => 'Str', ); # later required => 1 );
has 'color' => ( is => 'ro', isa => 'Str', );
has 'border' => ( is => 'ro', isa => 'Str', );
has 'found' => ( is => 'rw', isa => 'Sch_Symbol|Chip_Symbol|Net', );
1;
}
如果我尝试在 Perl 6 中做同样的事情,它会编译失败。
class Cell {
has Str $.str_val is required;
has Str $.x_id is required;
has Str $.color;
has Str $.border;
has Sch_Symbol|Chip_Symbol|Net $.found is rw
}
Malformed has at C:\Users\Johan\Documents/moose_sch_3.pl6:38 ------> has Sch_Symbol'<'HERE'>'|Chip_Symbol|Net $.found is rw
我如何在 Perl 6 中执行此操作?
您可能希望他们担任共同角色并将其指定为类型
role Common {}
class Sch-Symbol does Common {…}
…
class Cell {
…
has Common $.found is rw;
}
或者您将不得不使用 where
约束条件
class Cell {
…
has $.found is rw where Sch-Symbol|Chip-Symbol|Net;
}
您还可以创建一个子集来包装 where
约束。
subset Common of Any where Sch-Symbol|Chip-Symbol|Net;
class Cell {
…
has Common $.found is rw;
}
请注意,where
约束比使用普通角色慢。
你可以使用 where
has $.found is rw where Sch_Symbol|Chip_Symbol|Net;
或通过subset
subset Stuff where Sch_Symbol|Chip_Symbol|Net;
class Cell {
has Str $.str_val is required;
has Str $.x_id is required;
has Str $.color;
has Str $.border;
has Stuff $.found is rw;
}
这是 Brad Gilbert 在 subset/where
解决方案的完整实施。这包括 Common
中每个 类 的一个示例,以及一个显示不满足类型约束时会发生什么的示例:
#!/bin/env perl6
class Sch-Symbol { has Str $.name }
class Chip-Symbol { has Num $.num }
class Net { has Int $.id }
subset Common of Any where Sch-Symbol|Chip-Symbol|Net;
class Cell {
has Str $.str_val is required;
has Str $.x_id is required;
has Str $.color;
has Str $.border;
has Common $.found is rw;
}
my $str_val = 'foo';
my $x_id = 'bar';
my @founds = (
Net.new(:42id), # will work
Sch-Symbol.new(:name<baz>), # will work
Chip-Symbol.new(num => 1E101), # will work
42, # won't work
);
for @founds -> $found {
my $cell = Cell.new(:$str_val, :$x_id, :$found);
dd $cell;
}
假设这在文件 test.p6
中,当我们 运行 perl6 test.p6
时我们得到:
Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Net.new(id => 42)) Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Sch-Symbol.new(name => "baz")) Cell $cell = Cell.new(str_val => "foo", x_id => "bar", color => Str, border => Str, found => Chip-Symbol.new(num => 1e+101)) Type check failed in assignment to $!found; expected Common but got Int (42) in submethod BUILDALL at test.p6 line 9 in block <unit> at test.p6 line 28