Senia Lösung ist groß. Leider, wie er erwähnt hat, funktioniert das nicht für Map
noch String
. Hier ist eine weitere Alternative (basierend auf seiner Lösung), das tut:
import collection.generic.CanBuildFrom
import collection.breakOut
class Build[To]
def build[TargetSuperType] = new Build[TargetSuperType]
implicit def buildToCbf[From, T, TargetSuperType, To<:TargetSuperType](b: Build[TargetSuperType])
(implicit cbf: CanBuildFrom[Nothing,T,To]): CanBuildFrom[From,T,To] =
collection.breakOut
List(1, 2, 3).map{i => (i * 2, i/2.0, i.toString)}(build[Array[_]])
//res0: Array[(Int, Double, String)] = Array((2,0.5,1), (4,1.0,2), (6,1.5,3))
List(1, 2, 3).map{i => (i * 2, i.toString)}(build[Map[_,_]])
//res1: scala.collection.immutable.Map[Int,String] = Map(2 -> 1, 4 -> 2, 6 -> 3)
List('a', 'b', 'c').map(_.toUpper)(build[String])
//res2: String = ABC
Dieses kleine ausführlicher ist, weil Sie jetzt einfach nicht build[Array]
tun, aber build[Array[_]]
. Im Gegenzug können Sie unabhängig von der Anzahl der Typargumente eine beliebige Zielobjektgruppe angeben (z. B. Map
und String
).
Plus können Sie immer noch voll explizit sein (ähnlich wie bei breakOut
verwenden) wenn Sie wählen:
scala> List(1, 2, 3).map{i => (i * 2, i/2.0, i.toString)}(build[Array[(Int, Double, String)]])
res3: Array[(Int, Double, String)] = Array((2,0.5,1), (4,1.0,2), (6,1.5,3))
, dass alle mit der gleichen Syntax (in anderen Worten, mit dem gleichen Namen build
, wie gewünscht)
[Dies ist] (http://pastebin.com/rsmFtqdt) nicht was Sie wollen, aber ich denke, es ist das Beste, was Sie bekommen können. Dies funktioniert nicht für 'String' oder' Map'. – senia
Ja, das ist was ich wollte. Ich habe das gleiche gemacht, aber die generischen Parameter gemischt (T in def und A in code) und konnte es nicht aus dem Compiler-Fehler herausfinden. – IttayD
@senia Vielleicht eine Antwort machen? –