Подтвердить что ты не робот

Scala 2.10 - Октальный побег устарел - как сделать восьмеричную идиоматику сейчас?

См https://issues.scala-lang.org/browse/SI-5205 а также https://github.com/scala/scala-dist/pull/20

Значение Octal escape, ведущее 0, устарело от scala, и я не вижу идиоматической альтернативы.

Как вы справляетесь с восьмеричными в scala 2.10 сейчас?

Изменить - разрешения unix - восьмеричные

4b9b3361

Ответ 1

Литеральный синтаксис ушел (или уйдет, я думаю) и вряд ли вернется в любой форме, хотя были предложены альтернативы типа 0o700 .

Если вам нужно что-то более похожее на литерал компиляции во 2.10, вы можете использовать макросы (эта конкретная реализация вдохновлена ​​Macrocosm):

import scala.language.experimental.macros
import scala.reflect.macros.Context

object OctalLiterals {
  implicit class OctallerContext(sc: StringContext) {
    def o(): Int = macro oImpl
  }

  def oImpl(c: Context)(): c.Expr[Int] = {
    import c.universe._

    c.literal(c.prefix.tree match {
      case Apply(_, Apply(_, Literal(Constant(oct: String)) :: Nil) :: Nil) =>
        Integer.decode("0" + oct)
      case _ => c.abort(c.enclosingPosition, "Invalid octal literal.")
    })
  }
}

Затем вы можете написать следующее:

scala> import OctalLiterals._
import OctalLiterals._

scala> o"700"
res0: Int = 448

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

Ответ 2

Вы всегда можете BigInt("21",8), если хотите выполнить синтаксический анализ восьмеричного.

Ответ 3

Вот обновленная версия ответа @Travis Brown, на Scala 2.11

import scala.reflect.macros.blackbox
import scala.language.experimental.macros

object OctalLiterals {
  implicit class OctallerContext(sc: StringContext) {
    def o(): Int = macro oImpl
  }

  def oImpl(c: blackbox.Context)(): c.Expr[Int] = {
    import c.universe._

    c.Expr(q"""${
      c.prefix.tree match {
        case Apply(_, Apply(_, Literal(Constant(oct: String)) :: Nil) :: Nil) ⇒
          Integer.decode("0" + oct).toInt
        case _ ⇒ c.abort(c.enclosingPosition, "Invalid octal literal.")
      }
    }""")
  }
}