val bb =0
val cc ="%07d"
println(f"$bb$cc") //0%07d
println(f"$bb%07d") //0000000
我期待
println(f"$bb$cc"(//0000000
println(f"$bb%07d"(//0000000
为什么结果不一样?我怎样才能让它一样?
通过使用 f"string",您声明要制作格式化字符串。
使用 f"$bb$cc",您正在使用变量 bb 和 cc,因此它访问它们的字符串
使用 f"$bb%07d",您告诉它将 bb 转换为小数点后 7 位的数字,如果数字不够大,则转换为 0
有助于理解的更多示例:
val bb = 1
println(f"$bb%07d") // 0000001
println(f"$bb%05d") // 00001
val bb = 11
println(f"$bb%05d") //00011
要获取相同的字符串,请尝试使用 s"string">
val bb = 0
println(s"$bb%07d") // 0%07d
使用字符串作为格式化程序:
val cc = "%07d"
val bb = 0
println(cc.format(bb)) //0000000
欲了解更多信息 http://docs.scala-lang.org/overviews/core/string-interpolation.html
我想你已经知道了,但要清楚:
$
用于标记变量引用
%
用于格式化引用
通常你使用 f 插值器,如下所示: f"$<reference>%<format>"
当你写:
println(f"$bb$cc")
这是发生的情况:
- 解析器识别
$bb
,没有格式。 - 解析器识别没有格式的
$cc
。
用 0
代替$bb
用"%07d"
代替$bb
但是当你写:
println(f"$bb%07d")
这是发生的情况:
- 解析器通过格式化
07d
识别$bb
用 0
代替$bb
并根据"07d"
格式化,即:7 位数字,用 0 填充是数字短于 7 位数字。
您可能认为此方法像 C 中的#define cc "%07d"
一样进行预处理,但事实并非如此。
我目前不知道将格式存储在单独的字符串中的方法。您可以考虑使用基于类的格式化程序来执行此操作。
字符串内插语法需要字符串文本。
f插值器宏的要点是提供编译时安全性。
scala> val x = 0.1
x: Double = 0.1
scala> f"$x"
res0: String = 0.1
scala> f"$x%5.5f"
res1: String = 0.10000
scala> f"$x%5d"
<console>:13: error: type mismatch;
found : Double
required: Int
f"$x%5d"
^
scala> val fmt = "%5d"
fmt: String = %5d
scala> fmt format x
java.util.IllegalFormatConversionException: d != java.lang.Double
at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302)
at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2793)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2747)
at java.util.Formatter.format(Formatter.java:2520)
at java.util.Formatter.format(Formatter.java:2455)
at java.lang.String.format(String.java:2940)
at scala.collection.immutable.StringLike$class.format(StringLike.scala:318)
at scala.collection.immutable.StringOps.format(StringOps.scala:29)
... 32 elided
这不方便,但您可以分解字符串常量并手动滚动:
scala> final val fmt = "%5d"
fmt: String("%5d") = %5d
scala> new StringContext("", fmt).f(x)
<console>:14: error: type mismatch;
found : Double
required: Int
new StringContext("", fmt).f(x)
^
或
scala> final val fmt = "%5.5f"
fmt: String("%5.5f") = %5.5f
scala> new StringContext("", fmt).f(x)
res8: String = 0.10000
scala> final val fmt = "%5.5"
fmt: String("%5.5") = %5.5
scala> new StringContext("", fmt + "f").f(x)
res9: String = 0.10000
scala> new StringContext("", fmt + "d").f(x)
<console>:14: error: precision not allowed
new StringContext("", fmt + "d").f(x)
^
scala> final val fmt = "%5"
fmt: String("%5") = %5
scala> new StringContext("", fmt + "d").f(x)
<console>:14: error: type mismatch;
found : Double
required: Int
new StringContext("", fmt + "d").f(x)
^
如果您尝试使用非常量字符串,则会出现错误:
scala> val fmt = "%5d"
fmt: String = %5d
scala> new StringContext("", fmt).f(x)
<console>:14: error: exception during macro expansion:
java.lang.IllegalArgumentException: internal error: argument parts must be a list of string literals
at scala.tools.reflect.FormatInterpolator.scala$tools$reflect$FormatInterpolator$$copyPart$1(FormatInterpolator.scala:82)
at scala.tools.reflect.FormatInterpolator.interpolated(FormatInterpolator.scala:181)
at scala.tools.reflect.FormatInterpolator.interpolate(FormatInterpolator.scala:38)
at scala.tools.reflect.FastTrack$$anonfun$1$$anonfun$apply$5$$anonfun$applyOrElse$5.apply(FastTrack.scala:54)
at scala.tools.reflect.FastTrack$$anonfun$1$$anonfun$apply$5$$anonfun$applyOrElse$5.apply(FastTrack.scala:54)
at scala.tools.reflect.FastTrack$FastTrackEntry.apply(FastTrack.scala:41)
at scala.tools.reflect.FastTrack$FastTrackEntry.apply(FastTrack.scala:36)
at scala.tools.nsc.typechecker.Macros$class.macroExpandWithRuntime(Macros.scala:763)
new StringContext("", fmt).f(x)
^