Perl 6子类重写filter方法后传递方法作为参数报错求助
解决Perl 6中传递类方法作为参数时的参数数量错误问题
错误原因分析
你遇到的问题核心是没搞清楚Perl 6里方法和闭包的区别:方法调用必须依赖一个调用者(也就是self),而你直接传递&{self.filter}时,并没有正确绑定这个调用者,导致后续调用时参数匹配混乱。
具体来说,当你在print_filtered_list里写self.get_filtered_list(&{self.filter}),这里的self.filter是尝试调用方法,但缺少必要的参数$l;就算侥幸传递了方法对象,在get_filtered_list里调用&filter_method($l)时,Perl 6会把$l当成方法的调用者,而方法本身还需要一个参数,最终就会触发"参数过多"的错误。
解决方案
有两种简洁的修复方式,核心都是把方法转换成绑定了当前self的闭包:
方式1:用匿名闭包包装方法调用
修改print_filtered_list方法,用闭包明确包装self.filter($l)的调用,让闭包只接收$l作为参数:
method print_filtered_list() { my @outlist = self.get_filtered_list(-> $l { self.filter($l) }); say @outlist; }
方式2:使用Perl 6原生的方法引用语法
Perl 6提供了&.filter这种简洁语法,能直接生成绑定当前self的闭包,调用时只需要传入方法所需的参数即可:
method print_filtered_list() { my @outlist = self.get_filtered_list(&.filter); say @outlist; }
这种写法更符合Perl 6的风格,是推荐的做法。
修改后的完整代码
class list_filter { has @.my_list = (1..20); # 将在子类中重写的方法 method filter($l) { return True; } # 所有子类对象复用的打印方法 method print_filtered_list() { my @outlist = self.get_filtered_list(&.filter); say @outlist; } # 私有方法:执行过滤逻辑 method get_filtered_list(&filter_method) { my @newlist = (); for @.my_list -> $l { push(@newlist, $l) if &filter_method($l); } return @newlist; } } class list_filter_lt_10 is list_filter { method filter($l) { return $l <= 10; # 简化布尔表达式写法 } } class list_filter_gt_10 is list_filter { method filter($l) { return $l >= 11; # 简化布尔表达式写法 } } my $listobj1 = list_filter_lt_10.new(); $listobj1.print_filtered_list(); # 输出 (1 2 3 4 5 6 7 8 9 10) my $listobj2 = list_filter_gt_10.new(); $listobj2.print_filtered_list(); # 输出 (11 12 13 14 15 16 17 18 19 20)
额外优化说明
我还简化了子类中filter方法的写法,直接返回布尔表达式结果,让代码更简洁易读。
内容的提问来源于stack exchange,提问作者BhaskarS
相关产品推荐
相关产品推荐

