在Perl 6中,for-style循环中声明的变量位于外部作用域中.这工作和
is documented.
loop ( my $n = 0; $n < 3; $n++ ) { put $n; } say "Outside: $n";
$n在块外可见:
0 1 2 Outside: 3
这里是否存在激励技巧,这与Perl 6的祖先所期望的不同?我没有在设计文档中看到这一点(但尝试在某个时候搜索“循环”).我无法想出一个可以让事情变得更容易的例子.
在Perl 5中,同样的事情是严格的错误:
use v5.10; use strict; for ( my $n = 0; $n < 3; $n++ ) { put $n; } say "Outside: $n"; # Nope!
并且,在C(那些让你这样做),这是一个类似的错误:
#include <stdio.h> int main () { for( int a = 10; a < 20; a = a + 1 ){ printf("value of a: %d\n",a); } printf("value of a: %d\n",a); /* Nope! */ return 0; }
像往常一样我的问题,我对解决方法不感兴趣.我知道怎么做.
正如我在评论中所指出的,Synopsis 4推动实现仅在它们出现的块内声明词法.
$n出现在{之前,因为它不在“块内”.
然而,尖头块怎么样?
-> $a { put "a is $a" }
并且,子程序签名?
sub ( $a ) { put "a is $a" }
这些变量首先在{之前输入.
我并不特别关心这一点,但如果我必须通过说你必须在你将使用它们的块中声明词汇变量来解释这个传统的突破,有人可以指出这些情况.
解决方法
您可以将其视为块是创建词法范围的原因.
if (1) { my $a = 1; } $a; # error
if (my $a = 1) { } $a; # no error
loop (my $a = 1; $a == 1; ++$a) { } $a; # no error
只是其他类似C语言的特殊情况(C风格)for循环,而Perl 6设计是尽可能少的特殊情况.
因此,如果某个地方的东西非常有用,那么它应该被设计成可以在任何地方使用.
例如,数组中的-1索引.
而不是仅仅将@a [* – 1]作为特殊语法约束到数组索引,* -1只是一种创建lambda /闭包的方法,您可以在任何想要简单lambda的地方使用它.
另一个例子是尖头块不仅仅是一种在for循环中声明迭代变量的方法.
for @a -> $value {…}
它们可用于任何类似的构造.
if $a.some-resource-expensive-op -> $result {…}
代替
{ # note that $result isn't read-only like it is above my $result = $a.some-resource-expensive-op; if $result {…} }
您甚至可以将其用作创建lambda的另一种语法.
@a.sort: -> $value {…}
为了使语言更容易理解,特殊情况需要拉自己的权重,只有循环结构的参数,而没有其他构造,只是没有.
如果它通常有用那么它会有所不同.
此外,循环结构是少数几个与Perl 6的一般设计美学不相符的功能之一.我认为它可能更容易争论它的弃用和删除而不是它更特殊的套装.(没人争论要删除它)