Scala中的类型类模式涉及定义特征,例如:
trait Show[T] {
def show(obj: T): String
}
然后您可以定义此类型类的实例化:
object Show {
implicit val string = new Show[String] {
def show(obj: String): String = obj
}
implicit object BooleanShow extends Show[Boolean] {
def show(obj: Boolean): String = obj.toString
}
}
为伴随对象中的基本类型定义这些实例化的优点是,只要涉及类型类(大致),它们就会自动在范围内。
在功能上,它似乎将实例化定义为隐式val或隐式对象不会发生太大变化。
有区别吗?有一种方式比另一方好吗?
答案 0 :(得分:1)
val
和object
之间实际上不仅仅是类型名称。
你知道,Scala中的object
就像Java中的单例一样
也许您认为string
和BooleanShow
都在object
而不是class
,所以它们没有区别,但事实并非如此。
无论如何,它们都是val
和object
。
在Scala REPL中尝试此操作。
trait Show[T] {
def show(obj: T): String
}
object Show {
println("!! Show created")
implicit val string = new Show[String] {
println("!! string created")
def show(obj: String): String = obj
}
implicit object BooleanShow extends Show[Boolean] {
println("!!BooleanShow created")
def show(obj: Boolean): String = obj.toString
}
}
如果仅完成定义,则之后不会执行println
,因为Show
是一个有效的单例。它尚未创建。
接下来,在Scala REPL中执行Show
。
scala> Show
!! Show created
!! string created
res0: Show.type = Show$@35afff3b
您看到println
和Show
中的Show.string
被调用,但Show.BooleanShow
中的Show.BooleanShow
未被调用。{/ p>
您可以在Scala REPL中执行scala> Show.BooleanShow
!!BooleanShow created
res1: Show.BooleanShow.type = Show$BooleanShow$@18e419c5
。
Show.BooleanShow
val
最后被初始化了。它是一个单身人士,所以它是懒惰。
基本上,您的问题与val and object inside a scala class?相同,只是您在object
中定义了object
和val
,但链接的问题试图找出差异{{ 1 {}和object
在class
中定义,而val
中的方法使用反射(但您的使用覆盖,因此不涉及反射)。 implicit
基本上没有区别于它们。
我想您已经知道class
和object
之间的区别。更多信息可以在链接的问题中找到。
答案 1 :(得分:1)
因为他们总是使用显式类型来表示implicits,所以更喜欢val而不是object。
必要时让它变得懒惰。
精化:
scala> trait T
defined trait T
scala> object X { implicitly[T] ; object O extends T }
<console>:8: error: could not find implicit value for parameter e: T
object X { implicitly[T] ; object O extends T }
^
scala> object X { implicitly[T] ; implicit object O extends T }
<console>:8: error: could not find implicit value for parameter e: T
object X { implicitly[T] ; implicit object O extends T }
^
scala> object X { implicitly[O.type] ; implicit object O extends T }
defined object X
scala> object X { implicitly[T] ; implicit object O extends T ; implicit def y = O }
<console>:8: error: could not find implicit value for parameter e: T
object X { implicitly[T] ; implicit object O extends T ; implicit def y = O }
^
scala> object X { implicitly[T] ; implicit object O extends T ; implicit def y: T = O }
defined object X
O
的推断类型是单例类型O.type
。
答案 2 :(得分:0)
使用val x = new X { }
创建X
的匿名子类,而使用object x extends X
创建一个&#34;正确的&#34}。子类。我认为object
的开销很小,而@applicius指出,它有正确的名称。因此,我建议在这种情况下使用object
。