scala - 如何在类级别为隐式参数提供默认值

标签 scala

我正在尝试使用一些带有隐式参数的方法来定义一个类:

object Greetings {
  def say(name: String)(implicit greetings: String): String = greetings + " " +name 
}

我从另一个类(class)使用这个类(class)
implicit val greetings = "hello"                //> greetings  : java.lang.String = hello
Greetings.say("loic")                           //> res0: String = hello loic
Greetings.say("loic")("hi")                     //> res1: String = hi loic

我的问题是它只有在我在 Greetings 对象之外定义隐式 val 时才有效。
我希望能够提供带有隐式参数的方法,在我的类中使用默认值,以便更轻松地使用我的 API(如 Scala 集合 API)。

所以我想这样做,但它不起作用(找不到隐式值):
object Greetings {
  implicit val greetings = "hello"    
  def say(name: String)(implicit greetings: String): String = greetings + " " +name 
}

进而
Greetings.say("loic")                         
Greetings.say("loic")("hi") 

我知道我可以用 (implicit greetings: String = "hello") 定义一个默认值但我想在类里面做,如果有很多方法,避免重复。

我想我错过了一些东西,因为我看到了 CanBuildFromList 中定义类,例如。

最佳答案

使用像 String 这样的通用类型是一个坏主意。在一个隐含的。
主要原因是隐式查找完全基于类型,那么如果其他人定义了另一个字符串类型的隐式值呢?你可能会以冲突告终。因此,您应该为自己的目的定义自己的特定类型(字符串的简单包装器)。

另一个原因是,在查找隐式值时,编译器会(在其他地方)查找隐式值类型的伴随对象(如果有)。您可以很容易地看到它是多么有用,因为伴随对象是放置默认隐式值的自然位置(如您的情况)。但是,如果隐式值是您不拥有的类型(例如 String ),您就不能为其编写伴随对象,而使用您自己的包装器类型则没有问题。

好吧,废话太多了,这里是你如何做到的:

case class Greetings( value: String ) {
  override def toString = value
}
object Greetings {
  // this implicit is just so that we don't have to manually wrap 
  // the string when explicitly passing a Greetings instance
  implicit def stringToGreetings( value: String ) = Greetings( value ) 

  // default implicit Greetings value
  implicit val greetings: Greetings ="hello"

  def say(name: String)(implicit greetings: Greetings): String = greetings + " " +name 
}
Greetings.say("loic")                         
Greetings.say("loic")("hi") 

关于scala - 如何在类级别为隐式参数提供默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12767074/

相关文章:

scala - 如何使用类型标签/镜像在方法中获取构造函数参数?

scala - 选项方法签名,功能已在此范围内定义

scala - 获取对象中调用者类名称的最佳方法是什么?

scala - 为什么 Scala 的 Option[T] 不直接转换为字节码中的 T?

java - 在同一个项目中同时进行 Java 和 Scala 开发

scala - 如何在 Spark 中并行化 RDD/DataFrame 创建?

scala - SBT 本地 Maven 存储库依赖

scala - 如何解决此错误值toDS不是org.apache.spark.rdd.RDD的成员?

scala - 禁用 sbt 子项目文档生成

spring - Scala、@ResponseBody 和 map