相当于 scala 中的 python repr()

发布于 2024-12-11 14:59:05 字数 250 浏览 0 评论 0原文

scala 中是否有相当于 Python 的 repr 函数?

即,您可以给任何 scala 对象提供一个函数,它将生成该对象的字符串表示形式,该对象是有效的 scala 代码。

例如:

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

print(repr(l))

会产生

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

Is it there an equivalent of Pythons repr function in scala?

Ie a function which you can give any scala object an it will produce a string representation of the object which is valid scala code.

eg:

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

print(repr(l))

Would produce

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

转角预定愛 2024-12-18 14:59:05

每个对象大多只有 toString 方法。 (继承自 Java。)这可能会也可能不会产生可解析的表示。在大多数一般情况下,它可能不会; Python 中没有真正的约定,但一些集合类至少尝试这样做。 (只要它们不是无限的。)

当涉及字符串时,它当然已经达到了崩溃的程度

"some string".toString == "some string"

,但是,为了正确的表示,需要

repr("some string") == "\"some string\""

据我所知,Scala 中没有这样的东西。不过,一些序列化库可能对此有所帮助。

There is mostly only the toString method on every object. (Inherited from Java.) This may or may not result in a parseable representation. In most generic cases it probably won’t; there is no real convention for this as there is in Python but some of the collection classes at least try to. (As long as they are not infinite.)

The point where it breaks down is of course already reached when Strings are involved

"some string".toString == "some string"

however, for a proper representation, one would need

repr("some string") == "\"some string\""

As far as I know there is no such thing in Scala. Some of the serialisation libraries might be of some help for this, though.

月依秋水 2024-12-18 14:59:05

基于Java相当于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 字符会导致问题。

Based on the logic at Java equivalent of Python repr()?, I wrote this little function:

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("\"", "", "\"")
  }
}

I've tried it with a few values and it seems to work, though I'm pretty sure sticking in a Unicode character above U+FFFF would cause problems.

雨落星ぅ辰 2024-12-18 14:59:05

如果您处理案例类,您可以混合以下特征 StringMaker,这样即使它们的参数是字符串,在此类案例类上调用 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)

因此您可以解析回第一个表达,但不是第一个。

If you deal with case classes, you can mix in the following trait StringMaker, so that calling toString on such case classes will work even if their arguments are strings:

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)

will result in:

c_good: EString = EString("641", 151)
c_bad: EStringBad = EStringBad(641,151)

So you can parse back the firsst expression, but not the first one.

许仙没带伞 2024-12-18 14:59:05

不,Scala 中没有这样的功能。

No, there is no such feature in Scala.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文