我正在尝试使用一些带隐式参数的方法来定义一个类:
object Greetings {
def say(name: String)(implicit greetings: String): String = greetings + " " +name
}
Run Code Online (Sandbox Code Playgroud)
我从另一个班级使用这个班级
implicit val greetings = "hello" //> greetings : java.lang.String = hello
Greetings.say("loic") //> res0: String = hello loic
Greetings.say("loic")("hi") //> res1: String = hi loic
Run Code Online (Sandbox Code Playgroud)
我的问题是它只有在我的Greetings对象之外定义隐式val时才有效.我希望能够提供带有隐式参数的方法,在我的类中使用默认值,以便更容易地使用我的API(如Scala集合API).
所以我想这样做,但它不起作用(未找到隐含值):
object Greetings {
implicit val greetings = "hello"
def say(name: String)(implicit greetings: String): String = greetings + " " +name
}
Run Code Online (Sandbox Code Playgroud)
然后
Greetings.say("loic")
Greetings.say("loic")("hi")
Run Code Online (Sandbox Code Playgroud)
我知道我可以定义一个默认值,(implicit greetings: String = "hello")但我想在类级别进行,以避免重复,如果有很多方法.
我想我错过了一些东西,因为我看到它CanBuildFrom是在List类中定义的,例如.
Rég*_*les 26
String在隐式中使用这样的通用类型是个坏主意.主要原因是隐式查找完全基于类型,那么如果其他人定义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")
Run Code Online (Sandbox Code Playgroud)
我找到了一个解决方法:
class Greetings(implicit val greetings: String = "hello") {
def say(name: String): String = greetings + " " + name
}
Run Code Online (Sandbox Code Playgroud)
像这样我可以有一个默认值并覆盖它,如果我想:
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
Run Code Online (Sandbox Code Playgroud)
注意:new Greetings()("coucou")工作,而不是new Greetings("coucou"),因为这里解释了语法陌生.
| 归档时间: |
|
| 查看次数: |
10286 次 |
| 最近记录: |