如何在类级别的高级参数提供默认值(How to provide default value for

2019-08-01 05:45发布

我试图定义与一些方法以一个隐含参数类:

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

我使用这个类从另一个类

implicit val greetings = "hello"                //> greetings  : java.lang.String = hello
Greetings.say("loic")                           //> res0: String = hello loic
Greetings.say("loic")("hi")                     //> res1: String = hi loic

我的问题是,它只能如果我定义的隐含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")但我想这样做在一流水平,以避免重复,如果有很多方法。

我想我失去了一些东西,因为我看到了CanBuildFrom被内部定义List类,例如。

Answer 1:

这是一个坏主意,使用这种类型一般作为String中的隐式。 主要的原因是,隐性查找完全是基于该类型,所以如果别人定义String类型的另一个隐含的价值是什么? 你可能最终发生冲突。 所以,你应该定义为自己的目的,自己的特定类型(字符串周围的简单包装)。

另一个原因是,寻找隐含值时,编译器会看(在其他地方)到内含价值型的同伴对象(如果有的话)。 你可以很容易地看到它是多么有用,因为同伴目的是把一个默认的内含价值(如你的情况)的天然场所。 但是,如果隐含的价值是,你没有自己的类型(如String ),你就不能写一个同伴对象吧,同时用自己的包装类型是没有问题的。

OK,够空话,这里是你如何能做到这一点:

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") 


Answer 2:

我已经找到了解决办法:

class Greetings(implicit val greetings: String = "hello") {
    def say(name: String): String = greetings + " " + name 
}

像这样我可以有一个默认值,并覆盖它,如果我想:

new Greetings().say("loic")                     //> res0: String = hello loic

implicit val greetings = "hi"                   //> greetings  : java.lang.String = hi
new Greetings().say("loic")                     //> res1: String = hi loic

new Greetings()("coucou").say("loic")           //> res2: String = coucou loic

注: new Greetings()("coucou")是工作,而不是new Greetings("coucou")因为语法陌生感解释这里 。



文章来源: How to provide default value for implicit parameters at class level
标签: scala