如何将元组应用于 Scala 中的格式字符串? [英] How to apply tuple to a format string in Scala?
问题描述
我已经看过这个问题:将函数应用于元组在 Scala 中
理想情况下,我只想这样做:
Ideally I would simply like to do like this:
scala> val t = ("A", "B", "C")
t: (java.lang.String, java.lang.String, java.lang.String) = (A,B,C)
scala> "%-10s %-50s %s".format(t) // or some closer syntax
哪个应该给出输出
res12: String = A B C
编辑2
或者在某种意义上,Scala 编译器应该能够推断出我实际上是在使用正确的参数和类型进行调用,这样
Edit2
Or in some sense Scala complier should be able to infer that I am actually calling with correct arguments and types such that
"%-10s %-50s %s".format(t.untuple)
扩展为 "%-10s %-50s %s".format(t._1, t._2, t._3)
我可以使用宏来做到这一点吗?
Can I use a macro to do this?
我有一个用于格式化字符串的元组:
I have a tuple which I use for formatting a string:
scala> val t = ("A", "B", "C")
t: (java.lang.String, java.lang.String, java.lang.String) = (A,B,C)
scala> "%-10s %-50s %s".format(t.productElements.toList: _*)
warning: there were 1 deprecation warnings; re-run with -deprecation for details
res10: String = A B C
scala> "%-10s %-50s %s".format(t._1, t._2, t._3)
res11: String = A B C
到目前为止一切正常.但这失败了:
All works fine till now. But this fails:
scala> val f = "%-10s %-50s %s".format(_)
f: Any* => String = <function1>
scala> f(t.productElements.toList: _*)
warning: there were 1 deprecation warnings; re-run with -deprecation for details
java.util.MissingFormatArgumentException: Format specifier '-50s'
at java.util.Formatter.format(Formatter.java:2487)
at java.util.Formatter.format(Formatter.java:2423)
at java.lang.String.format(String.java:2797)
at scala.collection.immutable.StringLike$class.format(StringLike.scala:270)
at scala.collection.immutable.StringOps.format(StringOps.scala:31)
at $anonfun$1.apply(<console>:7)
at $anonfun$1.apply(<console>:7)
at .<init>(<console>:10)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:744)
这也失败了:
scala> f.apply(t)
java.util.MissingFormatArgumentException: Format specifier '-50s'
at java.util.Formatter.format(Formatter.java:2487)
at java.util.Formatter.format(Formatter.java:2423)
at java.lang.String.format(String.java:2797)
at scala.collection.immutable.StringLike$class.format(StringLike.scala:270)
at scala.collection.immutable.StringOps.format(StringOps.scala:31)
at $anonfun$1.apply(<console>:7)
at $anonfun$1.apply(<console>:7)
at .<init>(<console>:10)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:744)
我做错了什么?如何将元组参数应用于varagrs"样式函数?
What am I doing wrong ? How can I apply tuple parameters to a "varagrs" style function?
推荐答案
问题在于 lambda 定义
The problem is in lambda definition
val f = "%-10s %-50s %s".format(_)
相当于:
val f = x =>("%-10s %-50s %s".format)(x)
,
所以你只是在这里传递序列作为第一个参数.
So you're just passing sequence as first argument here.
正确的 lambda 是:(x: Seq[Any]) =>("%-10s %-50s %s".format)(x: _*)
甚至只是 val f: Seq[Any] =>String = "%-10s %-50s %s".format
Correct lambda is: (x: Seq[Any]) => ("%-10s %-50s %s".format)(x: _*)
or even just val f: Seq[Any] => String = "%-10s %-50s %s".format
示例:
scala> val f = x => ("%-10s %-50s %s".format)(x)
f: Seq[Any] => String = <function1>
scala> f(Seq(1,2,3))
java.util.MissingFormatArgumentException: Format specifier '-50s'
scala> val f: Seq[Any] => String = "%-10s %-50s %s".format
f: Seq[Any] => String = <function1>
scala> f(Seq(1,2,3))
res75: String = 1 2 3
可惜scala不理解("%-10s %-50s %s".format)(_: _*)
,所以不能使用下划线.
Unfortunately scala don't understand ("%-10s %-50s %s".format)(_: _*)
, so you can't use underscore.
这里有趣的是:如果您尝试使用下划线而不使用 apply 来做同样的事情 - 您将不必明确指定 _*:
What's interesting here: if you try to do same using underscore without apply - you won't have to specify _* explicitly:
scala> val f = ("%-10s %-50s %s": scala.collection.immutable.StringLike[_]).format _
f: Seq[Any] => String = <function1>
scala> f(Seq(1,2,3))
res81: String = 1 2 3
但是你必须明确指定类型类,因为 function _
构造 不适用于隐式.
But you have to specify type class explicitly because function _
construction doesn't work with implicits.
这篇关于如何将元组应用于 Scala 中的格式字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!