2016-04-01 11 views
2

Ich möchte Map implizit zu java.utils.Properties konvertiert werden.Scala implizite Konvertierung nicht auf sinnvoll Ziel

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   

Ich habe Map[String,String]() erste umgewandelt wird, so habe ich Object Typ zurück.

Warum nicht es die beiden Karte in Option und orElse zusammen konvertieren oder konvertieren Sie den Ausdruck träge am Ende? Wie kann ich tun, um es Eigenschaften angemessen zurückzugewinnen?

Antwort

0

Etwas Seltsames passiert mit impliziter Konvertierung und Rückgabetyp von getOrElse. Dies funktioniert jedoch:

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

und so tut dies

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

Ich bin nicht ganz sicher, warum der scala Compiler nicht die Konvertierung für Ihre Map finden. Aber ich vermute, es hat etwas mit (vielleicht) die Löschung und die Unterschrift von Option.getOrElse zu tun:

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

Das Ergebnis ist nicht unbedingt die gleiche Art wie die ursprüngliche Option, weil es auch ein superer Typ wie Map[Any, Any] sein könnte.

Es gibt mehrere Möglichkeiten, wie um diese Einschränkung zu umgehen:

Sagen Sie der Compiler das Ergebnis Typ getOrElse ausdrücklich:

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

Verwenden Sie einen Zwischenschritt, den Compiler zu sagen, dass die Option Eigenschaften enthalten sollte :

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])