相当于scala中的pythons repr()

时间:2011-10-21 14:56:21

标签: scala

scala中是否存在等效的Pythons repr函数?

即一个函数,你可以给任何scala对象,它将生成一个有效scala代码的对象的字符串表示。

例如:

val l = List(Map(1 -> "a"))

print(repr(l))

会产生

List(Map(1 -> "a"))

4 个答案:

答案 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中没有这样的功能。