我使用scala f string interpolator如下:
def format(id: Int) = f"A$id%04d"
format(21) // A0021
但是,我希望能够一劳永逸地定义一个长度(在固定为4之前),并获得一个函数,它将使用该长度格式化字符串 . 所以,而不是
def format(length: Int, id: Int) = ???
f(5, 21) // A00021
我想要这个:
def format(length: Int)(id: Int) = ???
val f = format(5)
f(21) // A00021
如何使用scala f插值器或其他实现此功能?
Update
我不是在运行时寻找涉及编译器的这种解决方案,但我很欣赏som-snytt的答案 . 这里有一个基于他的答案的工作解决方案:
import scala.tools.reflect._,scala.reflect.runtime._,universe._
def defFormat(length: Int): Int => String = {
val code = raw"""(i: Int) => f"A$$i%0${length}d""""
tb.eval(tb.parse(code)).asInstanceOf[Int => String]
}
val format = defFormat(length = 5)
format(21)
2 回答
编辑:
这实际上没有多大帮助 . 你真的想
如果格式不好则会抛出 .
你不能使用
f
这样做,因为它的重点是确保它可以检查格式字符串的类型错误,因此格式字符串必须是静态的 .f
可以明确支持这种情况,但事实并非如此 .你可以使
format
成为一个宏,但这看起来像是一种矫枉过正 . 更不用说它必须在一个单独的模块中定义,这对于这种情况看起来非常不方便 .