【问题标题】:What is the difference between A => 1 and 'A' => 1?A => 1 和 'A' => 1 有什么区别?
【发布时间】:2017-08-08 18:44:39
【问题描述】:

使用 Perl 6 REPL:

> Map.new: 'A' => 1, 'B' => 2;
Map.new((:A(1),:B(2)))
> Map.new: A => 1, B =>2;
Map.new(())

我之前认为A => 1 和'A' => 1 是相同的,因为=> 应该自动将单词放在其左侧,但在第二个示例中,这对似乎消失了。


免责声明:今天早些时候,这让我感到困惑,所以我将其发布为问答,以防它对其他人也有帮助。也可以随意添加您自己的答案。

【问题讨论】:

    标签: raku


    【解决方案1】:

    一般来说,A => 1 和 'A' => 1 创建等效的 Pair 对象。但是在子例程或方法调用中,第一个语法被解析为命名参数而不是 Pair。而在方法中,未使用的命名参数会被忽略,这就解释了您在第二个语句中创建的空Map。因此,您必须特别注意解析器不会将您的对解释为命名参数。以下都可以与命名参数区分开来:

    Map.new: (A=>1, B=>2);    # extra set of parentheses 
    Map.new: 'A'=>1, 'B'=>2;  # quote the keys
    Map.new: 'A', 1, 'B', 2;  # Don't use fat commas `=>`
    

    顺便说一句,这也说明了在方法调用中使用冒号: 而不是() 的另一个原因。使用括号可能不太干净:

    Map.new( A=>1, B=>2);  # oops, named arguments
    Map.new((A=>1, B=>2)); # extra set of parentheses solves the issue 
    

    【讨论】:

    • 这个问题的一部分是每个签名对于这些命名参数都有一个隐含的*%_。我已经开始在每个签名中添加*%_ () 以防止这种情况发生。我认为这种隐身行为对用户不利。
    • @briandfoy 同意
    • @briandfoy *% 在方法上的原因是因为 Liskov 替换原则。如果它没有,并且子类型重新定义了一个方法,那么如果用户给它一个它没有明确接受的命名参数,它就不会被调用。如果超类确实接受了该命名参数,它会默默地调用错误的方法。许多从事核心工作的人曾一度与您有相同的看法,但现在不同了。
    • 我知道他们做了什么。我仍然认为人们会讨厌它,这对于普通用户来说将是一个常见问题。
    • @BradGilbert 所以,如果我理解正确的话,如果对象没有将它们未使用的参数传递给它们的子类型,我们将会遇到其他令人困惑的静默失败。感谢您的解释。很高兴知道这实际上是一个经过深思熟虑的决定。
    【解决方案2】:

    在'A' => 1 中,'A' 是一个字符串,在A => 1 中,A 是一个标识符。


    为了演示相关概念,这里是一个虚构的讨论,包括一些问题和答案......

    如果键是句法标识符,并且它直接在参数列表中,那么它将被视为命名参数。否则它将是一对

    "foo" => "bar" 不是句法标识符,(foo => "bar") 不是直接在参数列表中,(:foo<bar>) 也不是。

    foo => "bar" 和 :foo("bar") 是等价的,并且都有一个作为句法标识符的键

    问题::ident<foo> 是否在参数列表之外提升为 "ident"=>"foo"?

    这是错误的方式。他们总是一对;但是,当它们位于参数列表的顶层时,它们会被提升为命名参数

    问题::2<> 和 :2nd 不是为了方便而成对吗?

    :2<> 是语法错误。

    :2nd 只是:nd(2)

    问:为什么不是 "2nd" => "True"?因为不是标识符?

    也因为它不是很有用 想象一下尝试实现 s:2nd/foo/bar/ 必须采用 slurpy 哈希并尝试从中解析出数字

    问:如果 : 后面的东西在基本情况下只能是一个标识符,那么用非标识符做事就好了..

    是的,后面的任何非标识符都是特殊形式

    【讨论】:

      猜你喜欢
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      相关资源
      最近更新 更多