我试图定义与一些方法以一个隐含参数类:
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
类,例如。
这是一个坏主意,使用这种类型一般作为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")
我已经找到了解决办法:
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")
因为语法陌生感解释这里 。