【问题标题】:dynamic string interpolation动态字符串插值
【发布时间】:2016-11-03 15:12:41
【问题描述】:

我想漂亮地打印一个Product,例如case class,所以我创建了以下特征:

  trait X extends Product {
    def fmtStrs =
      productIterator map {
        case _ : Double => "%8.2f"
        case _ => "%4s"
      } map (_ + separator) toSeq
    override def toString = {
      new StringContext("" +: fmtStrs : _*) f (productIterator.toSeq : _*)
    }
  }

这使用了 StringContext 的 ScalaDoc 中描述的字符串插值。

但这不会编译,出现这个神秘的错误:

Error:(69, 70) too many arguments for interpolated string
      new StringContext("" +: fmtStrs : _*) f (productIterator.toSeq : _*)

这是一个错误,还是宏的限制?请注意,执行以下操作很好,所以我怀疑这可能与变量参数列表有关:

scala> val str2 = StringContext("","%4s,","%8.2f").f(1,23.4)
str2: String = "   1,   23.40"

【问题讨论】:

  • 相当奇怪的是,如果您将 f 插值器更改为 s 插值器,这似乎符合(并且有效)...

标签: scala string-interpolation


【解决方案1】:

f 是一个宏的原因是,当格式说明符和参数的类型不匹配时,它会给您一个错误,而这无法通过查看 ("" +: fmtStrs : _*)(productIterator.toSeq : _*) 来检查,所以这不起作用也就不足为奇了。错误信息可能更清楚,所以让我们看看到底发生了什么。

如果你查看the implementation of f(我花了一些时间才真正找到它,我终于通过搜索错误消息找到了),你会看到

c.macroApplication match {
  //case q"$_(..$parts).f(..$args)" => 
  case Applied(Select(Apply(_, parts), _), _, argss) => 
    val args = argss.flatten
    def badlyInvoked = (parts.length != args.length + 1) && truly {
      def because(s: String) = s"too $s arguments for interpolated string"
      val (p, msg) =
        if (parts.length == 0) (c.prefix.tree.pos, "there are no parts")
        else if (args.length + 1 < parts.length)
          (if (args.isEmpty) c.enclosingPosition else args.last.pos, because("few"))
        else (args(parts.length-1).pos, because("many"))
      c.abort(p, msg)
    }
    if (badlyInvoked) c.macroApplication else interpolated(parts, args)

通过您的调用,您在partsargss 中都有一棵树,parts.length != args.length + 1 为真,所以badlyInvoked 为真。

s 不关心它的参数是什么样的,所以它只是一个方法,你的场景可以工作。

【讨论】:

  • 谢谢;为了记录,最后直接调用java.lang.String.Formatter而不是使用字符串插值。
猜你喜欢
  • 1970-01-01
  • 2017-05-24
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
  • 2015-08-15
  • 1970-01-01
  • 2022-07-01
  • 1970-01-01
相关资源
最近更新 更多