如何定义Scala包对象?

How to define Scala package object?

http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html提供以下示例:

1
2
3
4
5
6
7
8
// in file gardening/fruits/package.scala
package gardening
package object fruits {
  val planted = List(apple, plum, banana)              
  def showFruit(fruit: Fruit) {
    println(fruit.name +"s are"+ fruit.color)
  }
}

但是http://www.scala-lang.org/docu/files/packageobjects/packageobjects_1.html具有:

1
2
package gardening.fruits
object `package` { ... }

由于后一个示例将文件名与对象名匹配,并且在要为其定义包对象的包中包含该文件,因此看起来更可取。有什么区别(风格上除外)吗?


规范9.3说:

The standard naming convention is to place the definition above in a
file named package.scala that’s located in the directory corresponding
to package p.

这意味着反引号形式不是标准约定。

我同意没有足够的用户指南,尤其是在编译时交互方面。

区别在于您无法命名默认程序包。

1
2
3
4
5
6
7
object `package` {
  def f() = println("Hi")
}

object Foo extends App {
  f()
}

编辑:我更喜欢避免反引号(因为点击Tab或esc的危险很高),但是我只是有一个用例,我确实希望将代码放在一个源文件中,但是我也更喜欢避免包嵌套或相对package,因此反引号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.github.maqicode.deprecator

object `package` {
  // crashes scalac, actually
  implicit class MaybeInt(val s: String) extends AnyVal {
    def toInt_? : Option[Int] = if (s.isEmpty) None else convert
    private def convert = try { Some(Integer.parseInt(s))
    } catch { case _: NumberFormatException => None }
  }
}

// lots of code, so avoid package deprecator { ... }

case class Version(major: Int, minor: Option[Int], point: Option[Int], descriptor: String)

object Version {
  val version ="""(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(.*)""".r
  def apply(descriptor: String): Version = {
    val version(major, minor, point, rest) = descriptor
    Version(major.toInt, minor.toInt_?, point.toInt_?, descriptor)
  }
}

对于隐式问题,谁曾在Scala中使用默认程序包:我在测试代码中看到了它。

您说"不是文体上的"吗?嘿,这全都与风格有关。

我个人而言,我发现反引号是时髦的,但晦涩难懂。如果到了年底,每天我不得不额外挠头十次,那我会掉一些头发。

OTOH,如果我挠了下巴,然后走到"嗯"的程度,而不必刮胡子,那就可以了。

这不是这些课程的问题之一,是吗?