【问题标题】:Should I use $hash{"string"} or $hash{string} in Perl?我应该在 Perl 中使用 $hash{"string"} 还是 $hash{string} ?
【发布时间】:2010-11-30 22:28:09
【问题描述】:

在 Perl 中,哪一种是“更好”的风格?

$hash{"string"} or $hash{string}?

无论如何,它们的功能是否相同?

【问题讨论】:

  • 在 Perl 中,打破风格规则是好的风格!
  • 第一个版本更适合粘贴在 Stack Overflow 上的代码。
  • 你为什么在乎?真的。当然,您的代码中必须有更好的事情需要关心。只要他们的东西有效,我不在乎人们使用哪一个。
  • 我同意布赖恩的观点。为什么关心?如果以前有人问过问题,为什么还要问这个问题呢? stackoverflow.com/questions/401556/…
  • @brian & Manni -- 刚学习 Perl 的人可能会被外面的所有样式搞糊涂,而 Jessica 可能就是这样的人。她在学习语言时可能正在寻找“最佳实践”。如果它们在每种情况下都完全相同,那就太好了。既然不是,而且确实有很多“隐藏”的陷阱,那就更重要的是要知道。让她放松一下,好吗?

标签: string perl hash coding-style


【解决方案1】:

来自perldataperldoc:

事实上,此类卷曲中的标识符被强制为字符串,就像哈希下标中的任何简单标识符一样。都不需要引用。我们前面的例子,$days{'Feb'} 可以写成$days{Feb} 并且引号将被自动假定。但是下标中任何更复杂的东西都将被解释为表达式。这意味着例如$version{2.0}++ 等价于$version{2}++,而不是$version{'2.0'}++

所以是的,基本相同。但是要小心陷阱:

sub is_sub { 'Yep!' }

my %hash;
$hash{ is_sub   } = 'Nope';
$hash{ is_sub() } = 'it is_sub!!';

say Dumper \%hash;

将显示:

$VAR1 = { 'is_sub' => 'Nope', 'Yep!' => 'it is_sub!!' };

我的偏好是裸词...但如果您要调用 sub,请记住那些 () 或前面的 +(请参阅 jrockway 的评论和答案);-)

【讨论】:

  • 考虑到这一点,您关于$version{2.0}$version{'2.0'} 的示例让我感到困惑:perl -e '$foo{'2.0'}=1; print $foo{'2'}++, $foo{2}++, $foo{2.0}++, $foo{1+1}++, "\n";' 大括号中的值被评估为标量,并且该标量用作键。所以我不得不假设你没有测试你的例子,或者我在你想说的内容中遗漏了一些微妙的东西。 (对我来说它打印 1234
  • 不幸的是,您的示例不正确。实际上我很惊讶它甚至可以解析。你在 -e 和哈希索引中使用单引号。无论如何,如果您在设置后检查您的 $foo 哈希值,您会得到 { '2.0' => 1, '2' => 4 }... 这是您希望看到的答案
  • 你也可以用+function代替function()。
【解决方案2】:

它们在功能上是相同的,除非您的密钥中有空格或其他一些非字母数字字符。然后你必须使用引用的方法。

我不喜欢引用和使用包含 alpha_num 和下划线的名称。这让我大部分时间都不引用。

【讨论】:

  • 它们在功能上并不相同。在某些情况下,您会得到相同的结果,但原因不同。
  • 问题是 $hash{"string"} 是否与 $hash{string} 相同。
【解决方案3】:

避免使用引号更符合习惯。

编辑添加:

引用不是绝对可读性的解决方案。考虑这里的不一致:

sub function() { 'OH HAI' }
my @list = ('foo', 'bar', function); 
# ==> ('foo', 'bar', 'OH HAI')

my %hash;
$hash{'foo'} = 1;
$hash{'bar'} = 2;
$hash{function} = 3;
# ==> { foo => 1, bar => 2, function => 3 } (oops)

当你从不引用字符串时,“奇怪”的东西在视觉上与普通字符串不同......并且它被正确解析。

$hash{foo} = 1;
$hash{bar} = 2;
$hash{+function} = 3; # aha, this looks different... because it is
# ==> { foo => 1, bar => 2, 'OH HAI' => 3 }

(Stack Overflow 的语法高亮会搞砸这一点,所以请尽量忽略它。)

【讨论】:

    【解决方案4】:

    出于迂腐,我总是在哈希中引用我的字符串引用。它可以确保我不会遇到问题[1]。

    [1]我的 Perl 编码相当保守。

    【讨论】:

    • +1 因为这是一个合理的论点,尽管我倾向于不同意。
    • 您不同意它避免了某些问题吗?或者在风格上不同意?我很好奇。
    • 究竟有什么陷阱总是引用避免?
    • 如果你有一个 sub baz() {return 1} 怎么办?我不知道 foo{baz} 会做什么。我怀疑 baz 被插入到一个字符串中,但是,我不确定。我知道 foo{"baz"} 做了什么,我也知道 foo{baz()} 做了什么。
    • $foo{baz} 总是意味着 $foo{baz}。真的没有任何问题。如果 $foo{baz} 有时意味着别的东西,我会说这是一个陷阱,但它不是,所以它不是。
    【解决方案5】:

    大多数人更喜欢不带引号的形式,因为它更简洁整洁,只要哈希键仅限于字母数字和下划线。此外,大多数支持 Perl 语法的编辑器都知道如何将它们突出显示为字符串,尽管它们不在引号内。

    需要注意的是,不仅在使用散列键时,在定义散列、传递参数,甚至在使用=> 时定义列表时,都会出现这种行为。在前两种情况下,它可以帮助在视觉上区分您的键和值。例子:

    # Hash construction
    my %hash = ( 
        key1 => "val1",
        key2 => "val2" 
    );
    
    # Subroutine arguments
    some_function( arg1 => "val1", arg2 => $val2);
    sub some_function { my %args = @_; }; # arguments are pulled in as a hash
    
    # List construction (of course, not sure why you'd do this...)
    my @list = (Foo => "bar");
    print @list; # prints Foobar
    

    说了这么多,我开始引用所有内容,这是一个很难改掉的习惯。即使经过这么多年,引用您的哈希键也感觉“更安全”。

    【讨论】:

    • 不易出错?我看到不使用引号的人比使用引号的错误更多。请参阅 draegtun 的回答以获取一些示例。
    • @brian:是的,给出的两个例子很好,但并不完全模糊。句点在设置的字母数字 + 下划线之外,因此很容易捕捉。我个人也习惯于始终使用带有用户定义方法的括号,所以第二种形式也没有让我明白。但是,我向您的卓越体验低头,并从我的回复中删除了这句话。
    【解决方案6】:

    后一种格式$hash{string} 更简洁,但仅适用于字母数字和下划线。

    【讨论】:

      【解决方案7】:

      你应该总是$hash{"string"},除非你想要$hash{string}

      【讨论】:

        猜你喜欢
        • 2010-10-02
        • 2014-10-31
        • 2011-03-20
        • 1970-01-01
        • 2011-12-05
        • 1970-01-01
        • 2011-08-28
        • 2019-10-19
        • 2012-04-19
        相关资源
        最近更新 更多