2017-07-02 28 views
0

我怎么会做类似下面的(这显然是一个愚蠢的例子,但它足以说明我的问题):把隐含参数为范围从案例类体中

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内的构造函数。

回答

1

您可以在Scala中实例的import成员,以使它们的范围,和他们保持含蓄:

val test = MapBoolGetString("key") 
import test.map2bool 
test.getString(Map("key" -> "value")) 

作为一个侧面说明,没有任何理由来限定toStringgetString;如果您将U以外的内容传递给toString,则Scala会自动查找范围内的隐式转换。

Is there any way you can think of to achieve this w/o needing an explicit import statement? I'd love if it were some how part of the instantiating of a 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")) 
+0

有什么办法,你能想到的W/O需要一个明确的import语句来实现这一目标?如果它是某个MapBoolGetString实例化的一部分,我会很喜欢。 – user451151

+0

@ user451151请参阅编辑。 –