perl6 – Perl 6在键入数组时报告“无法取消装箱类型对象”
我怀疑这可能是Rakudo的一个错误,但我今天刚开始玩Perl 6,所以我很有可能犯了一个错误.在这个简单的程序中,在sub中声明一个类型化数组似乎会使Perl 6编译器生气.删除数组上的类型注释可以消除编译器错误.
这是一个简单的素数查找程序: #!/usr/bin/env perl6 use v6; sub primes(int $max) { my int @vals = ^$max; # forcing a type on vals causes compiler error (bug?) for 2..floor(sqrt($max)) -> $i { next if not @vals[$i]; @vals[2*$i,3*$i ... $max-1] = 0; } return ($_ if .Bool for @vals)[1..*]; } say primes(1000); 在Rakudo Star 2016.07.1(来自Fedora 24 repos)中,该程序给出以下错误: [sultan@localhost p6test]$perl6 primes.p6 Cannot unbox a type object in sub primes at primes.p6 line 8 in block <unit> at primes.p6 line 13 如果我删除vals数组上的类型注释,程序可以正常工作: ... my @vals = ^$max; # I removed the int type ... 我在使用Perl 6时犯了错误,或者这是Rakudo中的错误? 解决方法
您的代码中存在可能由类型检查捕获的错误
您收到的错误消息引起了对第8行的注意: @vals[2*$i,3*$i ... $max-1] = 0; 该行将=右侧的值列表分配给左侧的元素列表. 左边列表中的第一个元素@vals [2 * $i]得到零. 您没有在右侧定义任何更多值,因此左侧的其余元素被分配了一个 这个高尔夫版本可以获得相同的场景: my @vals; @vals[0,1] = 0; # assigns 0 to @vals[0],Mu to @vals[1] 如您所见,当您没有为@vals数组的元素指定显式类型约束时,一切正常. 这是因为数组元素的默认类型约束是Mu.因此,为元素分配Mu很好. 如果您觉得它收紧了代码,您可以明确指定零: @vals[2*$i,3*$i ... $max-1] = 0 xx Inf; 这在RHS上生成(惰性)无限的零列表,以便将零分配给LHS上的每个元素列表. 即使您为@vals指定了类型约束,只需进行此更改即可使用代码. 如果您没有引入xx Inf但是为@val指定了非Mu的元素类型约束,那么如果您尝试将Mu分配给@vals元素,则代码将无法进行类型检查. 类型检查失败将以两种风格之一出现,具体取决于您使用的是对象类型还是本机类型. 如果指定对象类型约束(例如Int): my Int @vals; @vals[0,1] = 0; 然后你得到一个像这样的错误: Type check failed in assignment to @vals; expected Int but got Mu (Mu) 如果指定本机类型约束(例如int而不是Int): my int @vals; @vals[0,1] = 0; 然后编译器首先尝试在尝试进行类型检查之前从对象值(这称为“拆箱”)生成合适的本机值.但是没有对应于对象值(Mu)的合适的原生值.所以编译器抱怨它甚至无法取消装箱值.最后,正如一开始所暗示的那样,虽然Mu作为一种类型安全的Null很有用,但这只是Mu的一个方面.另一个是它是“type object”.所以错误消息是无法取消打包类型对象. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |