Role约束变量不接受内联派生Role?$r2赋值可行性咨询
受Role约束的变量无法接受内联定义的派生Role问题
先看复现代码:
role R { } role S does R { } role T does S { } my R $r0 = T; # 编译通过 my R $r1 = role U does R { }; # 编译通过 my R $r2 = role V does S { }; # 编译错误: # Type check failed in assignment to $r2; expected R but got V (V)
问题:对$r2的赋值是否应该被允许?
我们的目标是实现类似如下的代码,把多个内联派生角色存入R类型的数组:
my R @r = ( role W does S { ... }, # 其他类似内联角色 ); my %h = @r.map: { .^name => $_ };
解答
应该允许对$r2的赋值,这是Raku类型检查逻辑中的一个边缘场景bug。
从类型系统的一致性来看:
- 命名角色
T通过S间接继承R,能正常赋值给R类型变量,符合角色继承的多态逻辑; - 内联角色
U直接继承R可以赋值,说明内联角色本身支持赋值给父角色类型的变量; - 但内联角色
V通过S间接继承R却触发类型检查失败,这明显违背了多态的一致性原则——无论角色是命名还是内联,只要最终符合目标约束角色的继承链,就应该被允许赋值。
针对你想要实现的数组存储场景,目前可以用两个变通方案绕过这个问题:
- 方案一:在内联角色声明时显式重复声明继承
R,比如role V does R does S { },虽然冗余但能通过类型检查; - 方案二:赋值时显式强制类型转换,比如
my R $r2 = role V does S { } but R;,或者my R $r2 = role V does S { } as R;。
内容的提问来源于stack exchange,提问作者zjmarlow
相关产品推荐
相关产品推荐

