在Scala 2.11标准库中,我们看到:
object StdIn extends StdIn
它带来了什么好处?没有其他类扩展这个特性。是否在函数调用中传递特征?单身对象有什么需要?
答案 0 :(得分:8)
您只需为特征本身混合的特征提供伴随对象即可实现无私特质模式。
trait Friendly {
def greet() { println("hi there") }
}
object Friendly extends Friendly
此示例中的Trait Friendly有一种方法,问候。它还有一个名为Friendly的伴侣对象,它混合了特质友好。鉴于这种友好的设计,这个库的客户端程序员可以通过组合混合访问Friendly的服务,这样(友好的导入和使用以粗体显示):
object MixinExample extends Application with Friendly {
greet()
}
或者通过导入友好伴侣对象的成员,如下所示:
import Friendly._
object ImportExample extends Application {
greet()
}
答案 1 :(得分:3)
首先,拥有一个扩展特征的对象并不会限制我们创建更多的特征实例。在假设的情况下,可能有另一个版本/实现超过StdIn
,我们可以声明以前的对象是过时的,保持相同的接口。但是,根据scaladoc,StdIn
的情况并非如此:
/** private[scala] because this is not functionality we should be providing
* in the standard library, at least not in this idiosyncractic form.
* Factored into trait because it is better code structure regardless.
*/
private[scala] trait StdIn {
特征定义对象的类型和接口。这对于引用该类型很有用。考虑没有特质的情况,使用时会很尴尬和限制:
scala> object A { val id = 1 }
defined object A
scala> def f(v: A.type) = v.id
f: (v: A.type)Int
scala> f(A)
res1: Int = 1
scala> def f(v: A) = v.id
<console>:10: error: not found: type A
def f(v: A) = v.id
不得不求助于结构化打字:
scala> def g(v: { def id: Int }) = v.id
g: (v: AnyRef{def id: Int})Int
scala> object B { val id = 2 }
defined object B
scala> g(B)
res5: Int = 2
scala> g(A)
res6: Int = 1
scala> f(B)
<console>:17: error: type mismatch;
found : B.type
required: A.type
f(B)
^
但是,我们无法使用StdIn
特征,因为它是私有的:
scala> import scala.io._
import scala.io._
scala> val b: StdIn = ???
<console>:13: error: trait StdIn in package io cannot be accessed in package io
val b: StdIn = ???
^
因此,您的问题非常合理,我看到的唯一好处是代码清晰度更高:抽象实现与实例/范围管理是分开的。