也许我遗漏了一些东西,但我想知道这段代码是否应该编译有充分的理由
role L {
method do-l (Int, Int --> Int ) { ... }
}
class A does L {
method do-l (Int $a, Real $b --> Str) {
.Str ~ ": Did you expect Int?" with $a + $b
}
}
my $a = A.new;
say $a.do-l: 2, 3.323
Run Code Online (Sandbox Code Playgroud)
这将输出
5.323: Did you expect Int?
Run Code Online (Sandbox Code Playgroud)
我很好奇是否有人知道编译器至少通过角色的实现签名抛出一些警告的方法L。
使用角色的已实现签名抛出一些警告
L。
如果你在方法声明前加上前缀 multi:
role L {
multi method do-l (Int, Int --> Int ) { ... }
}
Run Code Online (Sandbox Code Playgroud)
有了这个,您的程序将显示:
===SORRY!=== Error while compiling ...
Multi method 'do-l' with signature :(A: Int $, Int $, *%_ --> Int)
must be implemented by A because it is required by a role ...
Run Code Online (Sandbox Code Playgroud)
我想知道为什么这段代码应该编译[没有
multi]
我认为设计意图是支持多态组合的两个概念:
如果没有了multi,只执行涉及到用正确的方法存在名称; 参数被忽略。
随着对multi,实施覆盖的名字和所有参数,以及(或一些)。
我个人认为是否有充分的理由:
支持两种风格的方法多态?有时强制严格遵守签名是有帮助的。有时它会妨碍。
通过multi? 完全签名强制要求实现类/角色具有具有完全相同签名的方法。但是如果一个实现类/角色想要处理一个int而不是Int一个参数呢?乐妥协了。如果实现类/角色具有完全兼容的方法,它也可以有变化。传达这一点的完美方式是在存根方法前加上multi.
有默认的名称只有多态性吗?我们可以选择multi语义作为默认值,only如果用户只想要名称多态性,可以让他们写一个前缀。但这将扭转通常的情况(即忽略存根方法)。更一般地说,Raku 的目的是为其功能提供广泛的限制,从轻松到紧张,并为任何给定的功能选择一个默认值,根据多年来用户的反馈判断为正确。
如果默认值看起来不对怎么办?如果现有的限制范围不够怎么办?如果一组认为我们应该向左走而另一组认为我们应该向右走怎么办?
Raku 拥有 (imo) 卓越的治理机制来支持用户驱动的语言进化。在顶层有像编织结构这样的元素。在底层有像versionable types这样的元素。中间是诸如RoleToClassApplier调解将角色应用于类的过程的元素,这是需要找到所需方法或类的构造将失败的点。简而言之,如果语言不能按照您想要的方式工作,包括诸如限制之类的事情,您至少可以在原则上对其进行更改。