在对象后面有一个特征有什么好处?

Dra*_*orn 5 scala

在Scala 2.11标准库中,我们看到:

object StdIn extends StdIn
Run Code Online (Sandbox Code Playgroud)

它带来了什么好处?没有其他类扩展这个特性.是否在函数调用中传递特征?单身对象有什么需要?

slo*_*ouc 8

它被称为无私特质模式.

您只需为特征本身混合的特征提供伴随对象即可实现无私特征模式.

trait Friendly {
  def greet() { println("hi there") }
}

object Friendly extends Friendly
Run Code Online (Sandbox Code Playgroud)

Trait Friendly在这个例子中有一个方法,问候.它还有一个名为Friendly的伴侣对象,它混合了特质友好.鉴于这种友好的设计,这个库的客户端程序员可以通过组合混合访问Friendly的服务,这样(友好的导入和使用以粗体显示):

object MixinExample extends Application with Friendly {
  greet()
}
Run Code Online (Sandbox Code Playgroud)

或者通过导入Friendly伴侣对象的成员,如下所示:

import Friendly._

object ImportExample extends Application {
  greet()
}
Run Code Online (Sandbox Code Playgroud)


yǝs*_*ǝla 4

首先,拥有一个扩展特征的对象并不限制我们创建该特征的更多实例。在假设的情况下,可能会有另一个版本/实现取代StdIn,我们可以声明以前的对象已过时,并保持相同的接口。StdIn然而,根据scaladoc 的说法,这不是意图:

/** 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 {
Run Code Online (Sandbox Code Playgroud)

特征定义了对象的类型和接口。这对于引用该类型很有用。考虑一下没有特质的情况,使用起来会很尴尬并且受到限制:

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
Run Code Online (Sandbox Code Playgroud)

必须求助于结构类型:

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)
         ^
Run Code Online (Sandbox Code Playgroud)

但是,我们不能使用该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 = ???
              ^
Run Code Online (Sandbox Code Playgroud)

因此,您的问题是非常合理的,我看到的唯一好处是代码更加清晰:抽象实现与实例/范围管理分开。