【问题标题】:Scala syntactic sugarScala 语法糖
【发布时间】:2013-07-05 19:47:28
【问题描述】:

这是我的代码。我想写表达式 7? & 10?以便它编译。

object Test {
  trait A {
    def &(other: A) = ???
  }
  case class B(i: Int) extends A
  implicit class C(i: Int) {
    def ? : A= B(i)
  }
  val u = 7?
  val v = 10?
  val w = u & v // Ok, it compiles
  val z = 7? & 10?   //';' expected but 10 found
  val g = 7.? & 10?  //';' expected but 10 found
  val h = (7?) & 10? //Type mismatch. found Int(10). Required Test.A
  val i = 7? & (10?) //Test.A does not take parameters (on the ?)
}

为什么我不能写 7? & 10?是否可以将这个表达式写成 6 个字符,写得太不同了?

【问题讨论】:

  • 好吧,通过使用前缀符号 !而不是?,我可以保留我的六个字符!7 & !10

标签: scala syntactic-sugar


【解决方案1】:

Scala 编译器将 7 ? & 这行解释为简单的高阶方法调用:7.?(&),因为它是有效的 scala 代码,scalac 不会寻找隐式解析并抛出语法错误。

【讨论】:

  • 它仍然无法编译(Scala 2.10.2),因为它试图组成一个 Double 文字。
  • @0__ 是的,检查过,你是对的,但问题仍然在于方法调用解释
【解决方案2】:

正如 Alexiv 所指出的,问题是在将 postfix syntax 用于一元运算符之后,您无法放置二元运算符。后缀语法存在多个问题,这就是为什么 Scala 2.10 会警告您,除非您启用特殊语言功能。

所以理论上7.? & 10.? 应该可以工作。但是现在您遇到了整数和浮点文字之间的歧义问题。来自 Scala 语言规范 §1.3.2 “浮点文字”:

如果程序中的浮点字面量后跟一个以字母开头的记号,则这两个记号之间必须至少有一个中间空白字符。

所以这里的规则是用相反的方式定义的,即 Scala 似乎首先假设一个浮点数,然后再假设一个整数。 7.? 将被解释为Double 上的一个方法,而7.x 是Int 上的一个方法,如果你想在Double 上使用它,你必须写7. x。

没有怎么做相反的? 在句点之前放置一个空格:

7 .? & 10 .?

...当然只要使用括号就可以了

(7?) & (10?)

所以你没有得到你的 6 个字符,但是为什么需要这么短呢?

【讨论】:

  • 附带说明,Scala 将'$' 和'_' 定义为大写字母。你可以写7.$ & 10.$ 甚至7.$&10.$。但是谁会理解这种表达的含义呢?
  • 请注意,您可以从第二个 ? 之前删除句点,并添加一个隐式方法(以及您现有的隐式类) - 例如。 implicit def toA(i: Int): A = B(i) 您可以将括号放在第二个参数周围(即,编译您的 val h = (7?) & 10? 行)
  • @0__ 你不应该在生产代码中使用$ 和_,因为编译器会使用这些符号,并且很难找到错误
  • @Shadowlands 那么你也可以定义implicit class IntOps(i: Int) { def ?&(j: Int) = Incomplete(B(i), j) }; case class Incomplete(a: A, b: Int) { def ? : A = a & B(b) }并写成7?&10?。六个字。谁给我买啤酒?
【解决方案3】:

使用 -Xfuture 编译以在您的 int 上使用点分符号:

apm@mara:~/tmp$ scala -Xfuture 
Welcome to Scala version 2.10.1 (OpenJDK 64-Bit Server VM, Java 1.7.0_21).
[your stuff here]

scala> 7.? & 10.?
scala.NotImplementedError: an implementation is missing

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2015-03-26
    • 1970-01-01
    • 2010-12-06
    • 2023-03-06
    • 1970-01-01
    • 2011-04-21
    相关资源
    最近更新 更多