You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

能否在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

火山引擎 最新活动