Каков объем по умолчанию цикла foreach в Perl?

В Perl, делает использование 'моего' в цикле foreach, имеют какой-либо эффект? Кажется, что индексная переменная всегда локальна, используется ли 'мой'. Таким образом, можно ли отбросить 'мой' в цикле foreach и все еще иметь ли частный объем в теле цикла?

Как видно, с помощью 'для' цикла существует различие между использованием / не использование 'моего':

use strict; 
use warnings; 

my ($x, $y) = ('INIT', 'INIT'); 

my $temp = 0; 

for ($x = 1; $x < 10; $x++) {
 $temp = $x+1; 
}

print "This is x: $x\n";   # prints 'This is x: 10'. 

for (my $y = 1; $y < 10; $y++) {
 $temp = $y+1; 
}

print "This is y: $y\n";   # prints 'This is y: INIT'. 

Но на foreach это, кажется, не имеет эффект:

my ($i, $j) = ('INIT', 'INIT'); 

foreach $i (1..10){
    $temp = $i+1;
}

print "\nThis is i: $i\n";   # prints 'This is i: INIT'. 



foreach my $j (1..10){
    $temp = $j+1;
}

print "\nThis is j: $j\n";   # prints 'This is j: INIT'. 
16
задан skaffman 13 January 2012 в 10:49
поделиться

5 ответов

Из http://perldoc.perl.org/perlsyn.html#Foreach-Loops :

Цикл foreach выполняет итерацию по обычному значению списка и устанавливает переменную VAR как каждый элемент список по очереди. Если перед переменной стоит ключевое слово my, то она имеет лексическую область видимости и поэтому видна только внутри цикла. В противном случае переменная неявно является локальной для цикла и восстанавливает свое прежнее значение при выходе из цикла. Если переменная была ранее объявлена ​​с помощью my, она использует эту переменную вместо глобальной, но по-прежнему локализована для цикла. Эта неявная локализация происходит только в цикле foreach.

14
ответ дан 30 November 2019 в 21:28
поделиться

Я только что провел дополнительное исследование этого интересного вопроса.

foreach не волнует, если вы сделаете "my $y;" перед циклом. Итератор все равно будет меняться только в пределах области видимости:

my $y;
foreach $y (1..10) {}

$y будет меняться в области видимости foreach, но когда он выйдет, то вернется к тому, что было до цикла.

Я подумал, что, возможно, foreach автоматически выполняет "my $y;" перед началом выполнения, поэтому я попробовал строгий режим, но это объяснение не подходит, потому что тогда он по-прежнему требует:

foreach my $y (1..10) {}

в отличие от:

foreach $y (1..10) {}

... которые, как можно подумать, не нужны, если "foreach $y" функционально такой же, как "foreach my $y".

0
ответ дан 30 November 2019 в 21:28
поделиться
set serveroutput on;  
begin
   dbms_output.put_line('The');
   dbms_output.put_line('Quick');
   dbms_output.put_line('brown');
   dbms_output.put_line('fox');
end;
-121--3071447-

Если все ваши папки содержатся в одной папке, это должно быть довольно прямо вперед.

Dim path As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\YOURPATH"
System.IO.Directory.Delete(path, True)

Это приведет к удалению вашего корневого каталога и всех расположенных под ним каталогов и файлов. Вы могли бы просто вызвать это несколько раз, если ваши файлы и каталоги не все находятся в одном корневом каталоге, как «YOURPATH» в примере. Это избавит вас от необходимости удалять каждый файл по отдельности.

-121--1725367-

Итератор в петле foreach фактически является локальным по отношению к петле. Тем не менее, он непосредственно удерживает значение из списка в том, что фактически является вызовом по ссылке, а не по значению. Таким образом, при работе со значением в цикле значение в списке изменится. Однако переменная итератора определяется только в привязке к циклу:

@names = qw(Kirk Spock Bones);

$officer = "Riker";
print "@names $officer\n"; # will print Kirk Spock Bones Riker

foreach $officer (@names) {
     $officer .= "y";
}

print "@names $officer\n"; # will print Kirky Spocky Bonesy Riker

Таким образом, итератору, в данном случае $ officer, фактически предшествует «my» с точки зрения сохранения любого значения, которое он имел перед циклом foreach. Однако если значения, которые он хранит, будут изменены, то изменения вернутся в список, по которому выполняется итерация.

0
ответ дан 30 November 2019 в 21:28
поделиться

Ганс связался с документацией, описывающей, как переменная в цикле foreach является масштабируемой. Различие тонкое, но оно может быть важным:

sub f { return $i }
$i = 4;
$m = $n = 0;

foreach    $i (1 .. 10) { $m += f() }
foreach my $i (1 .. 10) { $n += f() }

print "Result with localization:    $m\n";    #  ==>  55
print "Result with lexical scoping: $n\n";    #  ==>  40
11
ответ дан 30 November 2019 в 21:28
поделиться

Объект Range имеет свойства width и height, которые измеряются в точках.

-121--1609743-

Просто добавьте заголовок к кнопке .

 < button title = "Hello World!" > Образец кнопки  
-121--580961-

Одним из самых болезненных открытий о Perl, которое я сделал, было то, что переменная "my" в цикле foreach не является локальной копией.

Единственный способ обойти кажется:


foreach ( @array ) {
  my $element = $_; # make a local copy
  ...
}

Если вы посмотрите на perldoc , он утверждает: "переменная индекса цикла foreach является неявным псевдонимом для каждого элемента в списке, который вы закольцовываете" и "Если любой элемент LIST является lvalue, вы можете изменить его, изменив VAR внутри цикла".

1
ответ дан 30 November 2019 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: