【问题标题】:Declare multiple variables on one line in perlperl在一行上声明多个变量
【发布时间】:2014-04-12 14:35:06
【问题描述】:

我发现我可以在一个语句中声明两个变量:

my ($a,$b)=(1,2);

但我认为这种语法可能会令人困惑,例如,如果我们有五个变量声明,则很难看出哪个值属于哪个变量。所以我认为如果我们可以使用这种语法会更好:

my $a=1, $b=2;

我想知道,为什么这种声明在 Perl 中是不可能的?还有其他选择吗?

(我试图避免为每个声明重复my,例如:my $a=1; my $b=2;

【问题讨论】:

  • “为什么”在这种情况下可能不是一个很有成效的问题。
  • @TLP,接收值的变量旁边的值更具可读性。重复my 很烦人而且很吵。这有点像 SQL 的 UPDATE 语法比它的 INSERT 语法更好。
  • 从技术上讲,您可以使用(my $a=1), (my $b=2);,但这似乎比my $a=1; my $b=2; 更糟糕。

标签: perl


【解决方案1】:

没有。 my 声明的变量只有在下一条语句开始时才会被命名。您可以分配给新创建的变量的唯一方法是分配给它返回的变量。将my 视为同样声明的new

至于您的特定代码,

my $a=1, $b=2;

意思

((my $a)=1), ($b=2);

显然,不好。

如果您使用了尚未声明的变量[1],则会收到严格错误。


  1. $a$b 在每个命名空间中都预先声明,以方便 sort 的使用。

【讨论】:

  • 感谢您的澄清!我觉得这个限制有点烦人,但我知道我必须忍受它,直到有人改进 perl 语言:)
  • 也许,但它允许open(my $fh, ...)while (my $line = <>) { }my $fh; open($fh, ...){ my $line; while ($line = <>) { } } 更轻松。总的来说,Perl 的方法胜过您建议的方法。也就是说,没有什么可以阻止声明语句(您想要的)和声明表达式(my)并行存在。声明语句甚至可以使用 CPAN 模块添加,方法与 Syntax::Feature::Loop 添加关键字 loop { ... } 相同。
  • @HåkonHægland:我认为值得指出的是,您不太可能需要在正确编写的 Perl 程序中一次声明和定义这么多变量。变量的声明应该尽可能接近它们的第一个使用点,如果您认为需要在程序的同一点创建五个或更多变量,那么也许您应该查看哈希或数组?我相信我在使用该语言的 15 年中从未见过这样的 Perl 代码。
【解决方案2】:

我是 Perl 的新手,但我会告诉你到目前为止我学到了什么。

我将改为使用$start$end 而不是$a$b,因为$a$b 是始终声明的特殊变量。

要回答您最初的问题,您可以在一行中声明和分配多个变量,如下所示:

my ($start, $end) = (1, 2);

就我个人而言,我发现这几乎是相同的输入,但不如将每个输入放在单独的行上清晰:

my $start = 1;
my $end = 2;

但是,我认为将子程序参数分配给命名变量很有用,因为子程序参数位于一个名为 @_ 的列表中:

use strict;

sub print_range {
    my ($start, $end) = @_;
    print "Range is from $start to $end.\n";
}

print_range(10, 20); # => Range is from 10 to 20.

您可以在the documentation 中看到my 语句的更多怪癖,包括忽略列表中某些值的方法。

【讨论】:

    【解决方案3】:

    下面是perl在一行中声明多个变量的方法:

    my ($day, $mon, $year, $hr, $min, $sec) = (0) x 6;
    

    这里,上面所有的变量都被初始化为0。使用了重复运算符'x'。

    【讨论】:

    • 这很好,但是可以通过自动计算 6 来完成,这样如果添加一个元素就不需要更改元素的数量吗?
    • @EvrenYurtesen:是的,它可以在您的逻辑中自动计算值 6,您可以将其用作变量。例如:我的 $repeat=6;我的 ($day, $mon, $year, $hr, $min, $sec) = (0) x $repeat;但是您需要检查如何管理赋值运算符的 LHS 部分。例如:如果你改变 $repeat=10 的值,在这种情况下,六个变量 my ($day, $mon, $year, $hr, $min, $sec) 将被赋值为 0。但是休息会丢失。因此,您需要检查这部分是否会保持重复值动态。
    • 如果你想保留声明的变量未定义你可以简单地做my ($day, $mon, $year, $hr, $min, $sec);
    • 我采用了这种方法。地图 { ($_) = '' } 我的 ($x, $y, $z);你不需要计算任何东西。我把 $_ 放在 () 中,让 perlcritic 误以为我知道自己在做什么 :)
    【解决方案4】:

    对于变量声明,我认为my ($a,$b)=(1,2);,正如所指出的,绝对足够了。

    但是对于哈希值初始化,你可以使用这个语法...

    my $stuff = {};
    
    $stuff->{hello} = $stuff->{thing} = 123;
    
    print(Dumper($stuff));
    

    这里的结果将是……

    $VAR1 = {
          'hello' => 123,
          'thing' => 123
    };
    

    这很简洁,因为您可以将不同数组不同键初始化为相同的值。

    您只能对每个值使用相同的值,但这对于哈希初始化来说可能是完美的。

    【讨论】:

    • 好吧,你可以使用任何语法。 Perl 标量赋值的结果是你赋值的值。如果你愿意,你可以拥有my $n = $var[$m] = $hash{$key} = $ARGV[0]
    【解决方案5】:

    我采用了这种方法。

    map { ($_) = '' } my ($x, $y, $z);
    

    用 0 替换数字的 ''。

    你不需要计算任何东西。

    我把 $_ 放在 () 中是为了让 perlcritic 误以为我知道我在做什么 :)

    我能想到的对变量值使用此方法的唯一方法是执行以下操作:-

    my @v = (1,23,'Bill',41);
    map {($_) = shift @v} my ($x,$y,$r,$s);
    

    或者如果已经定义了一些:-

    my $x = 7;
    my @v = (1,23,'Bill',41);
    map {($_) = shift @v} ($x,my ($y,$r,$s));
    

    【讨论】:

    • 这是一种非常邪恶的做事方式,如果你讨厌你的同事,这可能是可以接受的。但是,考虑到你还没有解决问题。您仍然必须在列表中获得正确数量的变量来映射,并且这些变量必须与 @v 中的相应内容对齐。你只是做了额外的工作,没有改善将正确的东西放在正确的位置的问题。我什至会说,你通过区分和混淆了什么与什么对齐,使情况变得更糟。
    • 你说得对,我也不会用这个。我还是喜欢 map { ($_) = '' } my ($x, $y, $z);用于定义/初始化多个变量
    【解决方案6】:

    为了避免在这些情况下混淆,通常可以这样做:

    my ($a, $b, $c, $d) = (
      1,  # => $a
      2,  # => $b
      3,  # => $c
      4   # => $d
    );
    

    根据KISS principle.


    ikegami 指出替代方案是:

    my $a = 1;
    my $b = 2;
    my $c = 3;
    my $d = 4;
    

    【讨论】:

    • 我认为这很糟糕。第二个更简单,更短,并且不容易出现错误的 cmets。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    相关资源
    最近更新 更多