Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何在类级别为隐式参数提供默认值_Scala - Fatal编程技术网

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

Scala 如何在类级别为隐式参数提供默认值,scala,Scala,我试图定义一个类,其中一些方法采用隐式参数: object Greetings { def say(name: String)(implicit greetings: String): String = greetings + " " +name } 我使用另一个类中的这个类 implicit val greetings = "hello" //> greetings : java.lang.String = hello Greetings.say(

我试图定义一个类,其中一些方法采用隐式参数:

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 collection API)的使用

所以我想这样做,但它不起作用(未找到隐式值):

然后

Greetings.say("loic")                         
Greetings.say("loic")("hi") 
我知道我可以用
(隐式问候语:String=“hello”)
定义默认值,但我希望在类级别这样做,以避免在有许多方法时重复


我想我遗漏了一些东西,因为我看到了
CanBuildFrom
是在
列表中定义的,例如。

我找到了一个解决方法:

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”)
,因为解释了语法上的奇怪之处。

在隐式语法中使用
String
这样的通用类型是个坏主意。 主要原因是隐式查找仅基于类型,所以如果其他人定义了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") 

这并不奇怪,因为implicit将只在正常参数之后插入。通常,您的类看起来像
类问候语()(隐式val…
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")