Scala 2.10 - 八进制转义已被弃用 - 现在如何习惯性地执行八进制转换?

时间:2013-05-16 14:30:59

标签: scala scala-2.10 idiomatic octal

请参阅 https://issues.scala-lang.org/browse/SI-5205https://github.com/scala/scala-dist/pull/20

从scala弃用了八进制转义值前导0,我没有看到惯用的替代方法。

你如何处理scala 2.10中的octals?

编辑 - unix权限是八进制

3 个答案:

答案 0 :(得分:17)

字面语法已经消失(或者说,我猜)并且不太可能以任何形式返回,尽管0o700 have been proposed等替代品。

如果你想在2.10中更像一个编译时文字,你可以使用宏(这个特定的实现是inspired by 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

现在你不需要在运行时解析字符串,并且在编译时捕获任何无效的输入。

答案 1 :(得分:10)

如果要解析八进制,则始终可以BigInt("21",8)

答案 2 :(得分:2)

以下是@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.")
      }
    }""")
  }
}