【问题标题】:Why is the `unary_` prefix needed in scala?为什么 scala 需要 `unary_` 前缀?
【发布时间】:2013-05-14 17:50:47
【问题描述】:

初学者 Scala 问题,但我在这里找不到答案。

类似于 C++ 中的重载,我希望编译器能够区分名为 - 的方法之间的区别,该方法采用一个参数(与类具有相同的类型)和不带参数的 - 的一元版本,那么为什么需要unary_

【问题讨论】:

    标签: scala


    【解决方案1】:

    一元前缀运算符unary_前缀有点误导:它更多的是关于前缀部分而不是一元部分。你需要一些方法来区分

    !foo // unary prefix !
    

    来自

    foo! // unary postfix !
    

    记住:Scala 实际上没有运算符。调用方法有两种方式,使用. 或使用空格:

    foo.bar(1, "two")
    foo bar(1, "two")
    

    当你有一个参数时,你可以去掉括号:

    foo plus(1)
    foo plus 1
    

    最后,(几乎)任何字符在标识符中都是合法的:

    foo plus 1
    foo + 1
    

    现在它看起来 Scala 有一个二进制中缀+ 运算符,但实际上没有。它只是一个普通的方法调用语法。

    然而,我上面所说的并不完全正确。如果 Scala 不支持运算符,而这一切都只是普通的方法调用,那么

    2 + 3 * 4
    

    将评估为 20(就像在 Smalltalk、Self 和 Newspeak 中所做的那样)而不是 14。因此,Scala 中对运算符有一点支持(实际上是两个小位) )。当使用空格(所谓的“运算符语法”)而不是 . 调用方法时,并且该方法以运算符字符开头,那么 Scala 将尊重运算符优先级。

    另外一点对操作符的支持是,有一些操作符是您喜欢 的,但它们不能轻易地表达为方法调用。它适用于二元中缀运算符和一元后缀运算符:

    foo op bar // same as:
    foo.op(bar)
    
    foo op     // same as:
    foo.op
    

    但不适用于前缀或“环绕修复”运算符:

    !foo
    foo(bar)
    

    所以,有一些特殊的语法糖翻译规则:

    !foo
    foo.unary_!
    // same for +, - and ~
    
    foo(bar)
    foo.apply(bar)
    
    foo(bar) = 1
    foo.update(bar, 1)
    
    foo += 1
    foo.+=(1) // but if this doesn't compile, then the compiler will also try
    foo = foo.+(1)
    

    而方法名称中的字母数字和“运算符”部分之间需要下划线的原因是因为您不知道是否

    foo!
    

    表示

    foo.!
    

    this.foo!
    

    所以foo!作为方法名是非法的,需要调用foo_!

    【讨论】:

    • 感谢您的详细解释和补充见解 :)
    • 由于这个答案似乎引起了一些关注:我缺少一些调用语法糖的方法吗?
    • “当使用空格(所谓的“运算符语法”)而不是 . 调用方法时,并且该方法以运算符字符开头,那么 Scala 将尊重运算符优先级。 @jhabbott 看这个:scala> 2.+3.*4 res10: Double = 14.0
    • @liango:在这种情况下,您使用的是运算符语法。它被解释为(2.) + (3.) * (4)。不过,您应该收到弃用警告;不推荐使用不带小数的浮点文字,并将在以后的版本中删除。
    【解决方案2】:

    因为在 scala 中创建一个名为- 的方法是完全可以的,它不需要任何参数。您如何区分普通方法和一元方法?例如,! 作为一元的含义与作为后修复运算符的含义完全不同。

    【讨论】:

    • 所以你可以让!xx! 都被称为! 并且不使用额外的参数并且编译器会知道这是两个不同的函数?它还会知道调用哪一个,因为它是在对象之前还是之后?
    • Jörg W Mittag 更详细地解释了我的回答想表达的内容 ;-)
    • 是的,谢谢-你们俩都投了赞成票 :) 我只是在学习,当您还不了解所有其他事情时,有些事情很难理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多