scala中是否存在等效的Pythons repr
函数?
即一个函数,你可以给任何scala对象,它将生成一个有效scala代码的对象的字符串表示。
例如:
val l = List(Map(1 -> "a"))
print(repr(l))
会产生
List(Map(1 -> "a"))
答案 0 :(得分:6)
每个对象上大多只有toString
方法。 (继承自Java。)这可能会也可能不会产生可解析的表示形式。在大多数通用情况下,它可能不会;没有真正的约定,因为在Python中有一些集合类至少会尝试。 (只要它们不是无限的。)
当涉及到字符串时,当然已经达到了分解的程度
"some string".toString == "some string"
然而,为了正确表示,需要
repr("some string") == "\"some string\""
据我所知,Scala中没有这样的东西。但是,有些序列化库可能对此有所帮助。
答案 1 :(得分:3)
根据Java equivalent of Python repr()?的逻辑,我写了这个小函数:
object Util {
def repr(s: String): String = {
if (s == null) "null"
else s.toList.map {
case '\0' => "\\0"
case '\t' => "\\t"
case '\n' => "\\n"
case '\r' => "\\r"
case '\"' => "\\\""
case '\\' => "\\\\"
case ch if (' ' <= ch && ch <= '\u007e') => ch.toString
case ch => {
val hex = Integer.toHexString(ch.toInt)
"\\u%s%s".format("0" * (4 - hex.length), hex)
}
}.mkString("\"", "", "\"")
}
}
我已经尝试了几个值并且它似乎有效,但我很确定坚持使用U + FFFF以上的Unicode字符会导致问题。
答案 2 :(得分:2)
如果你处理案例类,你可以混合使用以下特征StringMaker
,这样即使它们的参数是字符串,在这样的case类上调用toString也会有效:
trait StringMaker {
override def toString = {
this.getClass.getName + "(" +
this.getClass.getDeclaredFields.map{
field =>
field.setAccessible(true)
val name = field.getName
val value = field.get(this)
value match {
case s: String => "\"" + value + "\"" //Or Util.repr(value) see the other answer
case _ => value.toString
}
}
.reduceLeft{_+", "+_} +
")"
}
}
trait Expression
case class EString(value: String, i: Int) extends Expression with StringMaker
case class EStringBad(value: String, i: Int) extends Expression //w/o StringMaker
val c_good = EString("641", 151)
val c_bad = EStringBad("641", 151)
将导致:
c_good: EString = EString("641", 151)
c_bad: EStringBad = EStringBad(641,151)
所以你可以解析第一个表达式,但不能解析第一个表达式。
答案 3 :(得分:0)
不,Scala中没有这样的功能。