Bei zu vielen Argumenten wird String.format
Leicht zu verwirrend. Gibt es eine leistungsfähigere Möglichkeit, einen String zu formatieren? Wie so:
"This is #{number} string".format("number" -> 1)
Oder ist dies aufgrund von Typproblemen nicht möglich (format
würde vermutlich eine Map [String, Any] benötigen; ich weiß nicht, ob dies die Situation verschlimmern würde).
Oder geht das besser so:
val number = 1
<plain>This is { number } string</plain> text
obwohl es den Namensraum verschmutzt?
Bearbeiten:
In vielen Fällen reicht ein einfaches Zuhalten, aber ich suche auch nach etwas, das in die gleiche Richtung geht wie Pythons format()
(Siehe: http://docs.python.org/release/ 3.1.2/library/string.html # formatstrings )
In Scala 2.10 können Sie String-Interpolation verwenden.
val height = 1.9d
val name = "James"
println(f"$name%s is $height%2.2f meters tall") // James is 1.90 meters tall
Nun, wenn Ihr einziges Problem darin besteht, die Reihenfolge der Parameter flexibler zu gestalten, können Sie dies ganz einfach tun:
scala> "%d %d" format (1, 2)
res0: String = 1 2
scala> "%2$d %1$d" format (1, 2)
res1: String = 2 1
Und es gibt auch Regex-Ersatz mit Hilfe einer Karte:
scala> val map = Map("number" -> 1)
map: scala.collection.immutable.Map[Java.lang.String,Int] = Map((number,1))
scala> val getGroup = (_: scala.util.matching.Regex.Match) group 1
getGroup: (util.matching.Regex.Match) => String = <function1>
scala> val pf = getGroup andThen map.lift andThen (_ map (_.toString))
pf: (util.matching.Regex.Match) => Option[Java.lang.String] = <function1>
scala> val pat = "#\\{([^}]*)\\}".r
pat: scala.util.matching.Regex = #\{([^}]*)\}
scala> pat replaceSomeIn ("This is #{number} string", pf)
res43: String = This is 1 string
Vielleicht hilft Ihnen das Scala-Enhanced-Strings-Plugin. Schau hier:
Sie können eine umfangreichere Formatierung einfach selbst implementieren (mit dem Ansatz von pimp-my-library):
scala> implicit def RichFormatter(string: String) = new {
| def richFormat(replacement: Map[String, Any]) =
| (string /: replacement) {(res, entry) => res.replaceAll("#\\{%s\\}".format(entry._1), entry._2.toString)}
| }
RichFormatter: (string: String)Java.lang.Object{def richFormat(replacement: Map[String,Any]): String}
scala> "This is #{number} string" richFormat Map("number" -> 1)
res43: String = This is 1 string
Dies ist die Antwort, die ich hier gesucht habe:
"This is %s string".format(1)
Wenn Sie 2.10 verwenden, verwenden Sie die integrierte Interpolation. Andernfalls können Sie, wenn Sie sich nicht für extreme Leistung interessieren und keine Angst vor funktionierenden Einzeilern haben, eine Falz- und mehrere Regexp-Scans verwenden:
val template = "Hello #{name}!"
val replacements = Map( "name" -> "Aldo" )
replacements.foldLeft(template)((s:String, x:(String,String)) => ( "#\\{" + x._1 + "\\}" ).r.replaceAllIn( s, x._2 ))
Sie können auch die Verwendung einer Template-Engine für sehr komplexe und lange Zeichenfolgen in Betracht ziehen. Auf meinem Kopf habe ich Scalate , das unter anderem die Moustache Template-Engine implementiert.
Könnte für einfache Saiten ein Overkill und ein Leistungsverlust sein, aber Sie scheinen sich in dem Bereich zu befinden, in dem sie anfangen, echte Vorlagen zu werden.