chi*_*chi 5 types static-typing user-defined-types perl6
我想在Perl 6中定义两种数据类型,这些数据类型源自Int但不同时Int或彼此不兼容.
例如:
Distance派生自Int0到32000的范围,和Offset派生自Int-32000到32000的范围现在我想要这些类型Distance,Offset并且Int默认情况下可以区分并且彼此不兼容.
所以(伪Perl 6):
my Distance $d = Distance(12); // ok
my Offset $o = Offset(-1); // ok
my Distance $d2 = $o; // BUMMER!
sub myprint(Int $i) { say $i }
say $d + $o; // BUMMER!
myprint $d; // BUMMER!
myprint Int($d); // ok
Run Code Online (Sandbox Code Playgroud)
等等!如果我试图隐含地混合Distances和Offsets,我希望Perl 6编译器抱怨.
在我迄今读过的书中,没有提示如何实现这一点.问谷歌几天也没有给我任何答案是否可能,如果是,如何?
我发现subset但是这只对一个类型设置了一些限制,但是没有使它与原始类型不兼容.此外,如果在原始类型及其子集中都满足其限制,则它与原始类型无法区分.
所以我想在这里询问是否有人知道Perl 6中是否可以这样做?如果是的话,我该怎么办呢?
好吧,如果你真的希望它们在默认情况下是可区分的和不兼容的,只需将它们设置为完全独立的类即可。您可以定义您想要的任何能力。如果您使用与整数的“has a”关系(而不是“is a”关系),则可以很容易地将功能委托给该值(在本示例中,我进行了委托,.Int因此您的示例将起作用):
class Distance
{
has Int $!value handles<Int>;
method new($value where 0 <= * <= 32000) { self.bless(:$value) }
submethod BUILD(:$!value) {}
}
class Offset
{
has Int $!value handles<Int>;
method new($value where -32000 <= * <= 32000) { self.bless(:$value) }
submethod BUILD(:$!value) {}
}
my Distance $d = Distance.new(12); # ok
my Offset $o = Offset.new(-1); # ok
my Distance $d2 = $o; # Bummer! Type check fail
sub myprint(Int $i) { say $i }
say $d + $o; # Bummer!, can't add those objects
myprint $d; # Bummer!, $d isn't an Int, can't print
myprint Int($d); # ok, prints 12, converting with Int
Run Code Online (Sandbox Code Playgroud)
无论您想要什么功能Distance,都Offset必须构建到这些类中,可能会委托给 来$!value使其变得容易。
编辑:如果您确实想要所需的语法,my Distance $d = Distance(12);您可以向Int类添加一个方法来调用构造函数:
Int.^add_method('Distance', method () { Distance.new(self) });
Int.^compose;
Run Code Online (Sandbox Code Playgroud)
我实际上不会建议这样做——可能更令人困惑而不是有帮助。更好地鼓励标准构造函数的使用。@raiph 还指出了惯用的 Perl:
my Distance $d .= new(12);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
220 次 |
| 最近记录: |