gpt4 book ai didi

type-conversion - Perl6 类属性中的类型强制

转载 作者:行者123 更新时间:2023-12-04 07:01:13 28 4
gpt4 key购买 nike

像 Perl5 中的大多数东西一样,有很多方法可以创建一个支持自定义类型强制转换属性的类。这是一个简单的,从数组引用到散列:

#!/usr/bin/env perl

package Local::Class {
use Moo;
use Types::Standard qw( HashRef ArrayRef );

has set => (
is => 'ro',
coerce => 1,
isa => HashRef->plus_coercions(
ArrayRef, sub { return { map { $_ => 1} @{$_[0]} } },
),
);
}

my $o = Local::Class->new({ set => [qw( a b b c )] });
# $o->set now holds { a => 1, b => 1, c => 1}

我一直在尝试将这样的东西移植到 Perl6,在那里我需要的是一种强制 Array 的方法。到 SetHash .到目前为止,我能够做到这一点的唯一方法是这样的:

#!/usr/bin/env perl6

class Local::Class {
has %.set;
## Wanted to have
# has %.set is SetHash;
## but it dies with "Cannot modify an immutable SetHash"

submethod TWEAK (:$set) {
self.set = $set.SetHash;
}
}

my $o = Local::Class.new( set => [< a b b c >] );
# $o.set now holds {:a, :b, :c}

但这对我来说似乎不是正确的方法,至少对于将奇数列表传递给构造函数会使脚本死亡的微小细节。

那么,这是如何在 Perl6 中完成的呢?为类属性实现自定义类型强制的推荐方法是什么(因为我确定不止一种)?

最佳答案

TWEAK在对象被 BUILD 初始化后运行,这就是提供奇数数组的地方。

将强制移至 BUILD时间,事情应该按预期工作:

class Local::Class {
has %.set;
submethod BUILD (:$set) {
%!set := $set.SetHash;
}
}

如果您可以使用强制转换,那就太好了 SetHash()参数类型与自动属性初始化相结合,但这将失败,因为印记是属性名称的一部分,并且参数不能是 % -sigiled 如果你想接受非关联类型。

但是,如果您使用 $,它可以正常工作。 -sigiled 属性:
class Local::Class {
has $.set;
submethod BUILD (SetHash() :$!set) {}
}

正如@smls 指出的,以下变体
class Local::Class {
has %.set is SetHash;
submethod BUILD (:$set) {
%!set = $set.SetHash;
}
}

可能应该也能工作,而不是因无法修改不可变的 SetHash 而死。

作为 SetHash 的解决方法不可分配,您可以使用
class Local::Class {
has %.set is SetHash;
submethod BUILD (:$set) {
%!set{$set.SetHash.keys} = True xx *;
}
}

关于type-conversion - Perl6 类属性中的类型强制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40923729/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com