Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Scala中将元组应用于格式字符串? 编辑1_Scala - Fatal编程技术网

如何在Scala中将元组应用于格式字符串? 编辑1

如何在Scala中将元组应用于格式字符串? 编辑1,scala,Scala,我已经看到了这个问题: 理想情况下,我只想这样做: 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

我已经看到了这个问题:

理想情况下,我只想这样做:

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编译器应该能够推断我实际上是在用正确的参数和类型调用,比如

“%-10s%-50s%s”。格式(t.untuple)
扩展为
“%-10s%-50s%s”。格式(t.\u 1,t.\u 2,t.\u 3)

我可以使用宏来执行此操作吗

原来的问题如下 我有一个用于格式化字符串的元组:

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
到目前为止一切正常。但这失败了:

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>val f=“%-10s%-50s%s”。格式(\ux)
f:Any*=>字符串=
scala>f(t.productElements.toList:*)
警告:有1个弃用警告;有关详细信息,请使用-deprecation重新运行
java.util.MissingFormatArgumentException:格式说明符'-50s'
位于java.util.Formatter.format(Formatter.java:2487)
位于java.util.Formatter.format(Formatter.java:2423)
位于java.lang.String.format(String.java:2797)
位于scala.collection.immutable.StringLike$class.format(StringLike.scala:270)
位于scala.collection.immutable.StringOps.format(StringOps.scala:31)
在$anonfun$1.应用(:7)
在$anonfun$1.应用(:7)
在。(:10)
在
在。(:11)
在
$print()
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:606)
在scala.tools.nsc.explorer.IMain$ReadEvalPrint.call中(IMain.scala:704)
在scala.tools.nsc.explorer.IMain$Request$$anonfun$14.apply(IMain.scala:920)
在scala.tools.nsc.explorer.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
在scala.tools.nsc.io.package$$anon$2.run上运行(package.scala:25)
运行(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)
scala>f.apply(t)
java.util.MissingFormatArgumentException:格式说明符'-50s'
位于java.util.Formatter.format(Formatter.java:2487)
位于java.util.Formatter.format(Formatter.java:2423)
位于java.lang.String.format(String.java:2797)
位于scala.collection.immutable.StringLike$class.format(StringLike.scala:270)
位于scala.collection.immutable.StringOps.format(StringOps.scala:31)
在$anonfun$1.应用(:7)
在$anonfun$1.应用(:7)
在。(:10)
在
在。(:11)
在
$print()
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:606)
在scala.tools.nsc.explorer.IMain$ReadEvalPrint.call中(IMain.scala:704)
在scala.tools.nsc.explorer.IMain$Request$$anonfun$14.apply(IMain.scala:920)
在scala.tools.nsc.explorer.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
在scala.tools.nsc.io.package$$anon$2.run上运行(package.scala:25)
运行(Thread.java:744)

我做错了什么?如何将元组参数应用于“varagrs”样式的函数?

您可以如下定义
f

def f(t: Product) = "%-10s %-50s %s".format(t.productIterator.toList: _*)
然后您可以将其应用于
t

scala> f(t)
res1: String = A          B                                                  C
什么是
产品
scala.Product
是一种
特性
,由许多类实现,例如
Product2
Product3
。这些类依次是
Tuple2
Tuple3
的超级类型

简而言之,任何元组都是
产品
。这就是为什么
productIterator
在所有元组上都可用的原因

因此,要将元组用作vararg,一种方法是使用
productIterator
,并通过调用
toList
方法将其转换为
List

更好的签名 也许以下签名更适合您的功能:

 def f(fmt: String)(t:Product) = fmt(t.productIterator.toList: _*)
现在,您可以应用(或部分应用)它以获得所需的结果:

val res = f("%-10s %-50s %s")(t)
val newFormatter = f("%-10s %-40s %s")_
val newResult = newFormatter(t)

问题在于lambda的定义

val f=“%-10s%-50s%s”。格式()

相当于:

val f=x=>(“%-10s%-50s%s.”格式)(x)

所以你们只是在这里传递序列作为第一个参数

正确的lambda是:
(x:Seq[Any])=>(“%-10s%-50s%s.”格式)(x:u*)
,甚至只是
val f:Seq[Any]=>String=“%-10s%-50s%s.”格式

示例:

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

但是您必须显式指定类型类,因为
函数
构造。

我可以问一下为什么需要使用
元组
进行格式化吗?为什么不使用其他方法?例如,这是一种从一些值生成插值字符串的干净方法。我知道我可以使用字符串插值。我只想使用字符串格式化程序。对于字符串插值语法,我必须为元组使用下划线,这有点难看。请注意,您可以将
f
函数放在任意类中,并将其重命名为
格式
,然后提供从字符串到该类的隐式转换。然后,通过导入该隐式转换并启用隐式转换,您可以对字符串调用format方法并向其传递一个元组,如下所示:
“%s”。format(tuple)
,但这仍然不是我希望的类型安全方式。元组的所有成员都将转换为
Any
格式
函数本身键入为
Any*
,因此您必须接受它:)
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