隐式 def 和隐式 val 之间有什么区别?

What is the diff between implicit def and implicit val?

我有以下代码,我无法弄清楚,有什么区别:

  implicit def boxPrintable[A](implicit p: Printable[A]) =
    p.contramap[Box[A]](_.value)

  implicit val stringPrintable: Printable[String] =
    new Printable[String] {
      def format(value: String): String =
        "Foo " |+| value |+| " Too"
    }  

两者都是类型的实现。问题是,什么时候用def,什么时候用val

整个代码:

package com.sweetsoft

import cats.instances.string._
import cats.syntax.semigroup._
import cats.Contravariant
import cats.Show
import cats.instances.string._

final case class Box[A](value: A)

trait Printable[A] {
  self =>

  def format(value: A): String

  def contramap[B](func: B => A): Printable[B] =
    new Printable[B] {
      override def format(value: B): String = self.format(func(value))
    }
}


object Main {

  val showString = Show[String]

  implicit def boxPrintable[A](implicit p: Printable[A]) =
    p.contramap[Box[A]](_.value)

  implicit val stringPrintable: Printable[String] =
    new Printable[String] {
      def format(value: String): String =
        "Foo " |+| value |+| " Too"
    }

  implicit val booleanPrintable: Printable[Boolean] =
    new Printable[Boolean] {
      def format(value: Boolean): String =
        if (value) "yes" else "no"
    }

  def main(args: Array[String]): Unit = {
    println(format("Hello"))
    //println(format(Box("hello world")))
  }

  def format[A](value: A)(implicit p: Printable[A]): String =
    p.format(value)

}

您的 boxPrintable 接受类型参数 A 和类型 Printable[A] 的值参数,因此它必须是 def.

String 是一种特定的类型,所以 stringPrintable 根本没有参数,它只是一个常量,所以你可以将它定义为 val.

仅此而已。

def 对每个请求进行评估。

val 在创建 class 时计算。

在您的示例中,您需要一个 def,因为它具有参数,而 vals 是不可能的。