0

我需要用连接到变量的固定文本初始化一个字符串,如下所示:

   my $id = 0;
   my $text ="This is an example, id: ".$id."\n";

现在,在 0->9 的想象循环中,我只想修改$id值而不更改固定文本。我猜想使用引用应该像这样工作

for($i = 0; $i < 9; $i++) {
    my $rid = \$id;
    ${$rid}++;
    print $text;
}

想要的输出是

This is an example, id: 0
This is an example, id: 1
This is an example, id: 2

等等......但它不工作。

我误解了参考系统吗?

4

3 回答 3

3

您误解了参考系统。

my $id = 0;
my $text ="This is an example, id: ".$id."\n";

该文本在该点与 id 的值连接,在本例中为 0。该文本失去了与变量 $id 的所有连接。然后在循环中

for($i = 0; $i < 9; $i++) {
    my $rid = \$id;
    ${$rid}++;
    print $text;
}

您正在使用( 其中 in 成为at的另一个名称来增加$id变量, 但这对文本没有影响,因为它没有对变量的引用。$rid$idmy $rid = \$id;$id

做你想做的最干净的方法是使用闭包

my $id = 0;
my $textfunc = sub { return "This is an example, id: ".$id."\n" };

然后在你的循环中

for($i = 0; $i < 9; $i++) {
    $id++;
    print $textfunc->();
}
于 2013-03-25T16:41:20.173 回答
1

您似乎对引用感到困惑。也许您正在考虑以下 C 指针场景:

char text[] = "This is a test xx\n";
char *cursor = text + 15;
*cursor = ' 1';

不知道是怎样的思考过程会带来这样的印象,一旦你将 的内容内$id插进去my $x = "Test string $id",就可以通过改变 的值来改变内插字符串的值$id

正如我所说,你真的很困惑。

现在,如果您希望某个地方的子例程能够在不将输出格式嵌入子例程的情况下格式化某些输出,则可以将消息格式化程序作为参数之一传递给子例程,如下所示:

my $formatter = sub { sprintf 'The error code is %d', $_[0] };

forbnicate([qw(this that and the other)], $formatter);

sub frobnicate {
    my $args = shift;
    my $formatter = shift;

    # ...

    for my $i (0 .. 9) {
       print $formatter->($i), "\n";
    }

    return;
}

这肯定会变得乏味,因此您基本上可以拥有一个格式化程序包,并让潜艇使用他们需要的任何格式化程序:

package My::Formatters;

sub error_code {
    my $class = shift;
    return sprintf 'The error code is %d', $_[0];
}

在主脚本中:

use My::Formatters;

for my $i (0 .. 9) {
    My::Formatters->error_code($i);
}
于 2013-03-25T20:03:13.037 回答
1

正如思南指出的那样,有一种更简单的方法可以做到这一点。如果您想将$text字符串分开以实现可维护性和/或重用性,您也可以考虑使用sprintf,例如:

my $id = 0;
my $max_id = 9;
my $text = "This is an example, id: %d\n";

for (my $i = $id; $i < $max_id; $i++) {
    print sprintf($text, $i+1);
}
于 2013-03-25T19:15:14.550 回答