在Scala 2.11标准库中,我们看到:
object StdIn extends StdIn
Run Code Online (Sandbox Code Playgroud)
它带来了什么好处?没有其他类扩展这个特性.是否在函数调用中传递特征?单身对象有什么需要?
它被称为无私特质模式.
您只需为特征本身混合的特征提供伴随对象即可实现无私特征模式.
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)
首先,拥有一个扩展特征的对象并不限制我们创建该特征的更多实例。在假设的情况下,可能会有另一个版本/实现取代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)
因此,您的问题是非常合理的,我看到的唯一好处是代码更加清晰:抽象实现与实例/范围管理分开。
| 归档时间: |
|
| 查看次数: |
346 次 |
| 最近记录: |