Raku语言中如何过滤枚举成员生成目标枚举序列?
解决Raku枚举过滤问题:排除All和None成员
问题分析
你遇到的类型错误是因为A.enums返回的是Map类型,其中每个元素是Pair(比如:one(2)),但SetHash of A需要的是A类型的枚举对象,而非Pair,直接传入过滤后的Pair会触发类型检查失败。
解决方案1:创建过滤后的SetHash
如果你的需求是得到一个包含过滤后枚举成员的SetHash,可以直接迭代枚举类型本身(返回的是枚举对象),再过滤掉不需要的成员:
#!/usr/bin/env raku use v6.d; enum A <All None one two three four>; my SetHash of A $actions; # 直接迭代枚举类型A,过滤掉名称为All/None的成员 $actions .= new( A.grep( *.key !~~ /All|None/ ) ); say $actions.raku;
执行输出:
SetHash.new( {:one(A::one), :two(A::two), :three(A::three), :four(A::four)} )
代码说明
A作为枚举类型,直接迭代时会返回所有枚举成员的对象(如A::one、A::two)*.key获取枚举成员的名称字符串,通过!~~ /All|None/排除指定成员- 过滤后的结果是
A类型的对象集合,符合SetHash of A的类型要求
解决方案2:生成新的过滤后枚举类型
如果你的目标是创建一个新的枚举类型(仅包含one/two/three/four),可以先过滤原枚举的成员名称,再用这些名称定义新枚举:
use v6.d; enum A <All None one two three four>; # 过滤出不需要排除的枚举成员名称 my @filtered-names = A.enums.keys.grep( !/All|None/ ); # 使用过滤后的名称创建新枚举 enum FilteredActions (@filtered-names); # 测试验证 say FilteredActions::one; # 输出: one say FilteredActions.enums.raku; # 输出: Map.new((:one(0), :two(1), :three(2), :four(3)))
原双枚举方案无效的原因
你之前尝试的双枚举代码:
enum actions <one two three four>; enum full-set (actions.keys, <None All>).flat;
问题在于这种方式只是简单拼接字符串列表来定义枚举,无法关联原枚举的成员值,且如果原枚举有变更,需要手动同步。此外,若你期望full-set的成员值和最初的A枚举一致(比如All对应0、None对应1),这种方式无法实现,不如直接从原枚举过滤更可靠。
内容的提问来源于stack exchange,提问作者Richard Hainsworth
相关产品推荐
相关产品推荐

