эквивалент питонов repr () в scala - PullRequest
6 голосов
/ 21 октября 2011

Есть ли в scala эквивалент функции Pythons repr?

Т.е. функция, которую вы можете дать любому объекту scala, и она создаст строковое представление объекта, который является действительным кодом scala.

Например:

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

print(repr(l))

Будетпроизводить

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

Ответы [ 4 ]

6 голосов
/ 21 октября 2011

В большинстве случаев для каждого объекта используется только метод toString.(Унаследовано от Java.) Это может или не может привести к разбираемому представлению.В большинстве общих случаев это, вероятно, не будет;для этого нет реального соглашения, как в Python, но некоторые классы коллекций по крайней мере пытаются это сделать.(Пока они не бесконечны.)

Точка, в которой она разбивается, конечно, уже достигнута, когда задействованы строки

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

Однако для правильного представления необходимо

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

Насколько я знаю, в Scala такого нет.Однако некоторые библиотеки сериализации могут помочь в этом.

3 голосов
/ 19 февраля 2013

Основываясь на логике в 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("\"", "", "\"")
  }
}

Я пробовал это с несколькими значениями, и кажется,на работу, хотя я почти уверен, что вставка символа Unicode выше U + FFFF вызовет проблемы.

2 голосов
/ 17 мая 2013

Если вы имеете дело с классами case, вы можете смешать следующую черту StringMaker, так что вызов toString для таких классов case будет работать, даже если их аргументы являются строками:

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)

Таким образом, вы можете разобрать первое выражение, но не первое.

0 голосов
/ 21 октября 2011

Нет, в Scala такой функции нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...