当前位置: 首页 > 知识库问答 >
问题:

for循环中的变量被覆盖

关宏毅
2023-03-14

在for循环中,为不同的变量分配一个值。已经赋值的变量将从下一次迭代中获得赋值。最后,两个变量的值相同。该代码用于验证文件中的数据。当我打印这些值时,它会为第一次迭代打印正确的值,但在下一次迭代中,第一次迭代中指定的值会更改。当我在for循环中打印$value3和$value4的值时,它会为$value4显示null,为$value3显示一些值,但在下一次迭代中,$value3的值会被$value4的值覆盖

我已经尝试了rakudo perl 6. c

my $fh= $!FileName.IO.open;
my $fileObject = FileValidation.new( file => $fh );

for (3,4).list {

  put "Iteration: ", $_;
  if ($_ == 4) {
    $value4 := $fileObject.FileValidationFunction(%.ValidationRules{4}<ValidationFunction>, %.ValidationRules{4}<Arguments>);
  }

  if ($_ == 3) {
    $value3 := $fileObject.FileValidationFunction(%.ValidationRules{3}<ValidationFunction>, %.ValidationRules{3}<Arguments>);
  }

  $fh.seek: SeekFromBeginning;

}

共有2个答案

公羊凌
2023-03-14
匿名用户

可能发生的情况是,您返回的是一个容器而不是一个值,然后将容器别名为一个变量。

class Foo {
    has $.a is rw;
}

my $o = Foo.new( a => 1 );

my $old := $o.a;
say $old; # 1

$o.a = 2;
say $old; # 2

避免容器别名的一种方法是只使用。

my $old = $o.a;
say $old; # 1

$o.a = 2;
say $old; # 1

您还可以使用中的任意一种来取消该值的存储。自身或。

my $old := $o.a.<>;
say $old; # 1

$o.a = 2;
say $old; # 1

(注意<代码>。

暴德运
2023-03-14

TL;博士,目前无法自信地回答您的问题。这是一个nanswer——从某种意义上来说,这是一个答案,但也很可能不是一个帮助你解决问题的答案。

是例程或类属性上的rwtrait意味着它返回一个包含值的容器,而不仅仅是返回一个值。

如果然后为该容器别名,则可以获得所描述的行为。

例如:

my $foo;
sub bar is rw { $foo = rand }
my ($value3, $value4);
$value3 := bar;
.say for $value3, $value4;
$value4 := bar;
.say for $value3, $value4;

显示:

0.14168492246366005
(Any)
0.31843665763839857
0.31843665763839857

这不是语言或编译器中的错误。这只是P6代码在做它应该做的事情。

也许以上内容与您的代码相去甚远,让人迷失方向。因此,这里的内容与您提供的代码类似。

spurt 'junk', 'junk';

class FileValidation {
  has $.file;
  has $!foo;
  method FileValidationFunction ($,$) is rw { $!foo = rand }
}

class bar {
  has $!FileName = 'junk';
  has %.ValidationRules =
    { 3 => { ValidationFunction => {;}, Arguments => () },
      4 => { ValidationFunction => {;}, Arguments => () } }

  my ($value3, $value4);

  method baz {
    my $fh= $!FileName.IO.open;
    my $fileObject = FileValidation.new( file => $fh );
    my ($value3, $value4);

    for (3,4).list {

      put "Iteration: ", $_;
      if ($_ == 4) {
        $value4 := $fileObject.FileValidationFunction(
          %.ValidationRules{4}<ValidationFunction>, %.ValidationRules{4}<Arguments>);
      }

      if ($_ == 3) {
        $value3 := $fileObject.FileValidationFunction(
          %.ValidationRules{3}<ValidationFunction>, %.ValidationRules{3}<Arguments>);
      }

      $fh.seek: SeekFromBeginning;

      .say for $value3, $value4
    }
  }
}

bar.new.baz

这将输出:

Iteration: 3
0.5779679442816953
(Any)
Iteration: 4
0.8650280000277686
0.8650280000277686

布拉德和我得出了基本相同的答案(同时;我比布拉德领先一分钟,但谁在统计?我的意思是除了我之外?:),但布拉德很好地解决了这个问题:

避免容器别名的一种方法是只使用。

(毫无疑问,这也是为什么@ElizabethMattijsen要求尝试使用=而不是:=

您已经评论过,从:=更改为=没有什么区别。

但大概在整个代码库中,您并没有从:=更改为=,而是(相当于)您共享的代码中的这两个。

因此,也许问题仍然可以通过从:=切换到=来解决,但在其他地方的一些代码中。(也就是说,不要只是用=全局替换:=。相反,请确保您了解它们的区别,然后根据需要进行更改。您有一个测试套件,对吗?;)

现在你的问题得到了几张赞成票,没有反对票,你得到了两个答案(指向同一个问题)。

但也许我们的答案不够好。

如果是这样的话...

添加reddit注释,尝试使用=而不是:=,尝试使用最新的编译器,并对这些内容进行评论,这让我很高兴我没有否决你的问题,但我还没有对它投赞成票,这是有原因的。这是因为你的问题仍然缺少一个最小的可重复的例子。

您回应了我关于制作MRE的建议,包括:

问题是,我无法在更简单的环境中复制它

我推测这就是你的情况,但正如你所想象的,这意味着我们根本无法自信地复制它。出于各种原因,这可能是您喜欢的方式,但它违背了SO的指导(在上面的链接中),如果当前的答案不充分,那么明智的前进方式就是尽可能共享再现您的问题的代码。

如果它很大,请不要只是把它粘贴到你的问题中,而是链接到它。也许你可以在glot上设置它。io使用按钮使用多个文件(我想最多6个,另外还有一个标准输入)。如果没有,也许可以通过,比如,gist来实现。github。com,如果可以,我会在glot上设置它。io为您提供。

 类似资料:
  • 问题内容: 我试图用多个变量在Go中编写一个for循环。 来自javascript世界,我想实现以下目标: 我已经尝试过像这样的“原始翻译”: 但这是行不通的。正确的语法是什么? 非常感谢! 问题答案: 在Go中,您可以像这样循环执行多个变量分配。

  • 问题内容: 在循环内部声明变量是否不好?在我看来,这样做,如下面的第一个代码块所示,将使用第二次的十倍的内存…由于在循环的每次迭代中都创建了一个新的字符串。这样对吗? 与 问题答案: 在循环内部声明变量是否不好? 一点也不!它将变量本地化到其使用点。 在我看来,如下面的第一个代码块所示,这样做将使用十倍于第二个内存的内存。 编译器可以优化内容以保持内存使用效率。仅供参考:如果您使用关键字告诉您变量

  • 在for循环中为字符串定义值时遇到问题,但我需要它保持不变,即使在循环完成后也是如此。这是我的密码: 我知道如果我给soporte在for或if中赋一个值,它会改变,但我不知道如何做,因为它只是第一次问。还有,代码真的很长。这只是一个片段,所以有些东西是不完整的。P. D.apellido_1是用户的输入,但我使用了将要运行的示例。

  • 在循环中,我是否可以对循环使用相同的计数器变量? 或者这些变量会相互影响吗?以下代码应该为第二个循环使用不同的变量,例如,还是可以?

  • 出于某种原因,当我尝试运行这段代码时,它总是返回找不到符号。然后我发现问题是变量无法解析为变量。我不知道为什么它无法将其解析为变量。

  • 如下所示,我要反转数组。但我的代码不管用。这是我的for循环。请看一下。这个for循环正确吗。代码如下。