Scala隐式转换没有在sutiable目标上进行

时间:2016-04-01 04:00:20

标签: scala implicit-conversion implicit

我希望Map隐式转换为java.utils.Properties

implicit def map2Properties(map: Map[String, String]): Properties =
  map.foldLeft(new java.util.Properties) { case (p, (k, v)) => p.put(k, v); p }

val properties :Properties = Option(Map[String,String]("k"->"v")).getOrElse(Map[String, String]())

Error:(7, 82) type mismatch;
 found   : Object
 required: java.util.Properties           

我首先转换Map[String,String](),所以我得到了Object类型的回复。

为什么不将OptionorElse中的两个地图一起转换,或者最后懒洋洋地转换表达式? 我该如何才能让它返回属性?

2 个答案:

答案 0 :(得分:3)

我不确定为什么scala编译器无法找到Map的转换。但我怀疑它与(可能)擦除和Option.getOrElse的签名有关:

def getOrElse[B >: A](default: => B): B

结果不一定与原始选项的类型相同,因为它也可能是像Map[Any, Any]这样的超类型。

如何解决此限制有几种选择:

明确告诉编译器getOrElse的结果类型:

val properties2: Properties = Option(Map[String,String](("k","v"))).getOrElse(Map.empty[String, String]): Map[String, String]

使用中间步骤告诉编译器该选项应包含属性:

val propOpt: Option[Properties] = Option(Map[String,String](("k","v")))
val properties3: Properties = propOpt.getOrElse(Map.empty[String, String])

// or
val properties4: Properties = (Option(Map[String,String](("k","v"))): Option[Properties]).getOrElse(Map.empty[String, String])

// OR, shortest so far:
val properties5: Properties = Option(Map[String,String](("k","v")): Properties).getOrElse(Map.empty[String, String])

答案 1 :(得分:0)

使用隐式转换和返回类型的getOrElse进行奇怪的事情。 但是,这有效:

   Option(Map[String,String](("k","v"))).fold(Map[String,String]())(identity)

这样做

   Option(Map[String,String](("k","v"))).getOrElse[Map[String,String]](Map())