具有以下常规定义
sub bar( Int @stuff ) {
return [+] @stuff;
}
Run Code Online (Sandbox Code Playgroud)
以下两行均失败:
say bar( ^3 );
say bar( [1,2,3] );
Run Code Online (Sandbox Code Playgroud)
有错误
Type check failed in binding to parameter '@stuff';
expected Positional[Int] but got Array ($[1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
但是,使用相同的定义分配变量
my Int @works = [1,2,3] ;
say bar( @works );
Run Code Online (Sandbox Code Playgroud)
显然,变量分配和参数绑定不能以完全相同的方式工作,但这是因为类型检查很严格吗?
还是还有其他机制在起作用?
Jon*_*ton 11
分配是一项复制操作。当我们说:
my @a = @b;
Run Code Online (Sandbox Code Playgroud)
然后:
@b@a这就是为什么将来分配到@b(或pushes,或pops等)不会影响的原因@a。(顺便说一句,这也意味着my @a = [1,2,3]相当浪费,因为它构造了一个匿名对象Array,只能对其进行迭代,然后立即将其留给GC使用。)
当我们有:
my @a = 1, 2, 3;
my Int @b = @a;
Run Code Online (Sandbox Code Playgroud)
然后,对每个分配到的插槽中进行类型检查@b。重要的是价值观。当然,我们必须进行O(n)类型检查,但是=平均而言,语义意味着我们仍在进行O(n)操作。
相比之下,绑定是别名操作。它使符号引用成为值。它是O(1)操作。如果我们有:
my @a = 1, 2, 3;
my Int @b := @a;
Run Code Online (Sandbox Code Playgroud)
然后它必须失败,因为@a它没有受到适当的限制。我们不能仅仅@a检查它的值是Int; 一方面,它会改变操作的复杂性,使代码的性能难以推断,而且以后还@a可以例如1.5将其分配给它,从而使类型约束@b变得毫无意义,因为它使别名成为别名。一样。
参数传递通过绑定起作用,因此在问题中观察到的效果。
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |