我如何做以下事情(这显然是一个愚蠢的例子,但它可以说明我的问题):
trait GetString[T, U] {
def toString(u: U): String = u.toString
final def getString(t: T)(implicit f: (T) => U) = toString(f(t))
}
case class MapBoolGetString(name: String) extends GetString[Map[String, String], Boolean] {
/* This does not work */
implicit val map2bool = (m: Map[String, String]) => m.contains(name)
}
class Main {
val test = MapBoolGetString("key")
test.getString(Map("key" -> "value"))
}
这会导致错误:
No implicit view available from Map[String,String] => Boolean.
这显然是范围问题; map2bool
隐含不在范围内,因此getString
失败。
有没有办法可以把它带入范围?我把它放在MapBoolGetString
主体中的原因是因为我希望它依赖于name
中构造函数的map2bool
参数。
答案 0 :(得分:1)
您可以在Scala中import
个实例成员将它们纳入范围,并保持隐含性:
val test = MapBoolGetString("key")
import test.map2bool
test.getString(Map("key" -> "value"))
作为旁注,没有理由同时定义toString
和getString
;如果您将U
以外的内容传递给toString
,Scala会自动在范围内查找隐式转换。
有什么办法可以让你想到实现这个而不需要明确的导入声明吗?我很乐意,如果它是MapBoolGetString实例化的一部分。
不是真的,但如果你只需要一个隐含的,你可以这样做:
case class MapBoolGetString(name: String) extends GetString[Map[String, String], Boolean] with Map[String, String] => Boolean {
def apply(m: Map[String, String]) = m.contains(name)
}
// in Main
implicit val test = MapBoolGetString("key")
test.getString(Map("key" -> "value"))