syntax - 为什么 + 函数似乎适用于元组?

标签 syntax julia

对两个 Int64 的元组使用 + 函数会返回总和:

julia> +((1, 2))
3

但是,在引用元组的变量上使用 + 函数会出现以下错误:

julia> a = (1, 2)
(1,2)
julia> +(a)
ERROR: MethodError: no method matching +(::Tuple{Int64, Int64})

我无法理解为什么它会这样,尤其是当以下代码返回 true 时。

julia> typeof(a) == typeof((1, 2))

最佳答案

请注意,与您的想法相反,

julia> :(+((1, 2)))
:(1 + 2)

这是一个相当于 (+)(1, 2) 的单个函数调用。虽然语法可能看起来像有一个元组,但没有元组。 (正如您所指出的,+ 函数不适用于元组。)这种行为是否可取?好吧,它被报告为 bug #12755 ,但随后固定。但修复导致 bug #12771这导致修复被 pull #12772 恢复.

解决这个困惑问题的方法是避免在没有显式编写括号的情况下将运算符作为函数调用。也就是说,始终写 (+)(1, 2)而不是+(1, 2) 。您可以验证(+)((1, 2))抛出您期望的错误。

(此问题仅发生在一元运算符中,因此 |* 不受此问题的影响。)

<小时/>

如果您感兴趣,这个问题的核心是 +(x, y) 之间的根本模糊性。函数调用语法和一元运算符语法。以下是一些激发解析的情况 +-作为一元运算符,即使后面跟着 ( :

  • -(x+y)^2 ,很有可能(-)((x+y)^2)的意思是,不是 ((-)(x+y))^2 。所以我们不能简单地无条件解析-(作为函数调用。
  • 相反,必须做的是 - 之后的事情解析到一定的优先级,这样 -x * y被解析为 (-x) * y , -x + y(-x) + y ,但是-x^y-(x^y) .
  • 异常(exception):但这会使 -(1, 2)解析为(-)((1, 2)) ,即在元组上调用的函数。无论出于何种原因,我们决定为 - 之后的内容添加一个异常(exception)。看起来像一个函数调用元组。这样+(1, 2)可以,但这实际上主要只是一种黑客攻击。
  • 但是从解析器的角度来看,((1, 2))看起来一模一样(1, 2) ;只是前者用括号括起来。

我个人的观点是-(1, 2)表示法很愚蠢(并且并非在所有情况下都有效;例如在 -(1, 2)^2 中)。如果该异常不存在,并且 -(1, 2)一致地解析为元组上的一元函数调用,然后可以在没有(我认为)太多损失的情况下获得更高的一致性。只写 1 - 2 也不错。或(-)(1, 2)当需要二进制函数调用时。

关于syntax - 为什么 + 函数似乎适用于元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43262045/

相关文章:

syntax - `impl TraitX for TraitY` 在 Rust 中意味着什么?

julia - 可视化 Julia 类型树

julia - 如何在模块内部使用模块外部的函数

c++ - 没有可行的重载 '='

arrays - Julia 语言: sub vs. slice函数

Julia 执行速度

julia - 获取 Julia Lang 中当前变量的列表

ruby - 如何使 Ruby 变量在条件表达式中的计算结果为 false

javascript:捕获元素名称和元素的字符串值的语法

php - 如何在 PHP for() 循环中的简写 if/else 语句中使用变量?