能否在Raku中实现类似C++的auto类型推断以触发编译时错误?
在Raku中实现类似C++
auto的静态类型推断 首先先明确你的场景和需求:你定义了一个强类型的Raku子程序:
sub abc(Int $n) { say $n }
- 当传递显式声明为Str类型的变量时,编译器会直接抛出编译时错误:
my Str $s = "123"; abc $s; - 但如果传递无类型约束的变量(默认类型为
Any),只有在程序运行时才会报错:my $s = "123"; abc $s;
你希望实现类似C++ auto的机制,让变量能自动推断为值的具体类型,进而在调用abc时触发编译时错误——答案是完全可以,Raku原生就支持这种能力!
最简单的实现:使用::=进行静态类型推断
Raku里的::=操作符就是专门用来做静态类型推断的,它会根据右侧值的类型,自动把变量的静态类型绑定为该具体类型,完美对应你想要的auto效果。
把你的代码改成这样:
sub abc(Int $n) { say $n } # 用::=替代=,自动推断$s为Str类型 my $s ::= "123"; abc $s; # 编译阶段直接报错!
这段代码在编译时就会抛出错误:Type check failed in binding to parameter '$n'; expected Int but got Str ("123"),完全符合你的预期。
可选:自定义auto关键字(更贴近C++写法)
如果你想让语法更贴近C++的auto,也可以自定义一个trait来实现,不过日常开发里::=已经足够简洁,这个方法仅作扩展参考:
# 自定义is auto trait sub trait_mod:<is>(Mu \var, :$auto!) { var.WHAT.set_default_type(var.VALUE.WHAT); } sub abc(Int $n) { say $n } # 用is auto实现类型推断 my $s is auto = "123"; abc $s; # 同样触发编译时错误
补充:为什么默认的my $s = "123"不行?
默认的赋值语法my $s = "123"会把变量的静态类型设为Any(Raku的顶层父类型),变量只是在运行时持有一个Str值,但编译器不会在编译阶段做类型校验。而::=会直接把变量的静态类型锁定为右侧值的具体类型,让编译器能提前捕获类型不匹配的问题。
内容的提问来源于stack exchange,提问作者dharmatech




