为什么Scala API有两种组织类型的策略?

Yuv*_*ory 4 import scala packages traits

我注意到Scala标准库使用两种不同的策略来组织类,特征和单例对象.

  1. 使用其成员为导入的包.例如,这是您访问的方式scala.collection.mutable.ListBuffer.这种技术很熟悉来自Java,Python等.

  2. 使用特征的类型成员.例如,这是您访问该Parser类型的方式.你首先需要混入scala.util.parsing.combinator.Parsers.这种技术不熟悉来自Java,Python等,并且在第三方库中使用不多.

我猜(2)的一个优点是它组织了方法和类型,但根据Scala 2.8的包对象,可以使用(1)完成相同的操作.为什么要有这两种策略?什么时候应该使用?

Dan*_*ral 5

这里注意的命名法是路径依赖类型.那是你所说的2号选项,我只会说它.除非您碰巧遇到问题,否则您应该始终选择1号选项.

你错过的是Parser该类引用了Parsers类中定义的东西.实际上,Parser类本身取决于input已定义的内容Parsers:

abstract class Parser[+T] extends (Input => ParseResult[T])
Run Code Online (Sandbox Code Playgroud)

类型Input定义如下:

type Input = Reader[Elem]
Run Code Online (Sandbox Code Playgroud)

而且Elem是抽象的.例如,考虑RegexParsersTokenParsers.前者定义ElemChar,而后者定义为Token.这意味着Parser每个人都是不同的.更重要的是,因为Parser是它的子类Parsers,Scala编译器将确保在编译时你没有传递RegexParsers's Parser,TokenParsers反之亦然.事实上,你甚至无法将Parser一个实例传递RegexParsers给它的另一个实例.