scala - 在 Scala 中提供类型类的实例时使用 vals 还是 object 更好

标签 scala typeclass implicit

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 或隐式对象不会有太大变化。

有区别吗?一种方法比另一种更好吗?

最佳答案

val之间实际上不止是类型名称和 object .

你知道,object在 Scala 中类似于 Java 中的单例。
也许你认为两者都是stringBooleanShowobject不是 class所以它们没有区别,但事实并非如此。

他们是 valobject无论。

在 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 s 之后执行,因为 Show实际上是单例。它尚未创建。

接下来,执行 Show在 Scala REPL 中。
scala> Show
!! Show created
!! string created
res0: Show.type = Show$@35afff3b

你看,println s 在 ShowShow.string被调用,但在 Show.BooleanShow 中的那个不是。

您可以执行 Show.BooleanShow下一个在 Scala REPL 中。
scala> Show.BooleanShow
!!BooleanShow created
res1: Show.BooleanShow.type = Show$BooleanShow$@18e419c5
Show.BooleanShow终于被初始化了。它是一个单例,所以它是 懒惰 .

基本上,您的问题与 val and object inside a scala class? 相同除了您的 valobjectobject 中定义,但链接的问题试图找出差异 valobjectclass 中定义以及 val 中的方法使用反射(但你的使用覆盖,所以不涉及反射)。 implicit基本上没有区别它们是什么。

我想你已经知道 class 之间的区别了和 object .更多信息可以在链接的问题中找到。

关于scala - 在 Scala 中提供类型类的实例时使用 vals 还是 object 更好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25515790/

相关文章:

haskell - 为什么 Haskell 中没有元组的 "general"访问器函数?

scala - 在Scala中,为什么无法从类型别名或依赖类型推断出TypeTag?

java - 将 nscala-time 日期时间转换为 java.util.Date

java - GHA 中的单元测试因 java.lang.IllegalArgumentException : Unsupported class file major version 55 失败

scala - 确保隐式定义始终具有更高/更低优先级的一般方法

haskell - 数字类型的相等性如何工作?

scala - 在 Scala 中递归使用隐式方法

C-函数隐式声明时间,rand,printf,我所有的函数调用

scala - 在 Scala 中编写级联 if 语句的更好方法?

scala - 拆分使用Prepend [A,B]串联的HList