【问题标题】:Why do I need a parentheses for my ternary operator when appending to a string?附加到字符串时,为什么我的三元运算符需要括号?
【发布时间】:2020-06-20 06:32:45
【问题描述】:

我正在用 Ruby 练习以下问题。 https://leetcode.com/problems/defanging-an-ip-address/

我发现我需要在我的三元运算符中添加一个括号才能获得与具有 if/else 条件的等效代码行相同的结果。这是为什么 ?

# @param {String} address
# @return {String}
def defang_i_paddr(address)
  return address if address.isEmpty?

  result_from_ternary = ''
  result_from_if = ''

  address.each_char do |letter|
    # Why do I need parentheses here ?
    result_from_ternary << (letter == '.' ? '[.]' : letter)

    # Why dont I need parentheses here ?
    result_from_if << if letter == '.'
                        '[.]'
                      else
                        letter
                      end
  end
  result_from_ternary = ''
end

【问题讨论】:

  • @knut 解释了为什么需要括号,但您需要关注的不仅仅是那些。假设letter = '.'res = '' 你执行:res &lt;&lt; (letter == '.' ? (String.new 'cat') : (String.new 'dog')) #=&gt; "cat"。没问题,但如果你执行res &lt;&lt; (letter == '.' ? String.new 'cat' : (String.new 'dog')),你会得到...syntax error, unexpected ':', expecting ')'...。同样,res &lt;&lt; (letter == '.' ? (String.new 'cat') : String.new 'dog') 会引发语法异常。 This article 可能感兴趣。
  • 虽然括号在 Ruby 中是可选的,但在尝试指示解释器或编译器理解代码的操作顺序时,它们很重要,就像在所有其他语言中一样。在进行代码审查时,我总是强调这一点,因为依靠解释器或编译器来正确处理它是有风险的,尤其是在凌晨 3 点,当你有点宿醉并处理其他人编写的代码时。 “始终编写代码,就好像最终维护您的代码的人将是一个知道您住在哪里的暴力精神病患者。代码可读性。” — 约翰·伍兹

标签: ruby string conditional-operator


【解决方案1】:

让我们看看这个例子:

a1 = []
a1 << 1 == 2 ? 'a' : 'b'
p a1  #[1]

a2 = []
a2 << ( 1 == 2 ? 'a' : 'b')
p a2 #["b"]

没有括号,代码a1 &lt;&lt; 1 == 2 ? 'a' : 'b' 被评估为a1 &lt;&lt; 1,结果 ([1]) 与 2 进行比较。根据结果 (false) 三元运算返回“b”。

如果您将测试更改为!=,则结果为a

例子:

p    a1 << 1 == 2 ? 'a' : 'b'
p    a1 << 1 != 2 ? 'a' : 'b'

当您设置括号时,首先评估命令1 == 2 ? 'a' : 'b'。然后将结果 (b) 添加到数组中。

【讨论】:

    【解决方案2】:

    原因是运算符优先级。当没有括号来指导 Ruby 时,Ruby 会首先计算优先级较高的运算符。

    查看table of Ruby operator precedence,您可以看到&lt;&lt; 的优先级高于==? : 运算符。

    这意味着,Ruby 会解释

    result_from_ternary << letter == '.' ? '[.]' : letter
    

    按此顺序

    ((result_from_ternary << letter) == '.') ? '[.]' : letter
    

    这显然不是您想要的,因此您需要通过添加括号来“覆盖”默认优先顺序:

    result_from_ternary << (letter == '.' ? '[.]' : letter)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 2019-02-08
      • 2015-05-31
      • 2022-06-13
      • 2019-10-08
      • 2020-08-13
      相关资源
      最近更新 更多