Scala中的类型安全格式化输出

时间:2014-06-28 19:33:47

标签: scala printf

我在想是否可以在Scala中实现类型安全的printf。假设我们只需要支持字符串文字%s %d

我希望printf("This is number %d", 0)能够被编译,但printf("This is number %d", "abc")不会被编译。

我希望printf在编译时检查参数的数量。因此printf("This is a literal")会被编译,但printf("This is number %d and string %s", 0)不会。

我已经看到它可以用宏来完成。是否绝对有必要实现类型安全的printf

2 个答案:

答案 0 :(得分:5)

Scala的f字符串格式化程序已经是一种类型安全的printf。它是使用宏实现的。例如:

scala> val s = "not a number"
s: String = not a number

scala> f"$s%d"
<console>:9: error: type mismatch;
 found   : String
 required: Int
              f"$s%d"
                 ^

答案 1 :(得分:2)

这是尝试在没有宏的情况下实现这样的事情。可能有一种不那么丑陋的方式......应该添加一些额外的方法以使其更方便。

import scala.language.implicitConversions

package test {

  sealed trait End
  sealed trait Prove[T]
  object Prove{
      implicit object EndProve extends Prove[F[End,End]]
  }

  class F[A,B](ss: List[String]){
    def _d(s: String) = new F[Int,F[A,B]](s :: ss)
    def _s(s: String) = new F[String,F[A,B]](s :: ss)
  }

}

package object test {

  implicit def string2F(s: String) = new F[End,End](List(s))


  def printf[A,B](a: A)(f: F[A,B])(implicit ev: Prove[B]) = ???

  def printf[A,B,C](b: B, a: A)(f: F[A,F[B,C]])(implicit ev: Prove[C]) = ???

  def printf[A,B,C,D](c: C, b: B, a: A)(f: F[A,F[B,F[C,D]]])(implicit ev: Prove[D]) = ???

  // and so on...
}

正如您所看到的那样(如果您实施实际打印):

scala> import test._
import test._

scala> printf(4, "string")("a digit: " _d " and a String: " _s ".") // compiles
scala.NotImplementedError: an implementation is missing

scala> printf(4, 6)("a digit: " _d " and a String: " _s ".") // doesn't compile
<console>:11: error: type mismatch;

scala> printf(4)("a digit: " _d " and a String: " _s ".")  // doesn't compile
<console>:11: error: type mismatch;