Scala 2.10 - 八进制转义已被弃用 - 现在如何更好地使用八进制?

16

2
引用Seth Tisue的话:「八进制文字是马车时代的东西」。几乎没有人使用它们,几乎每个人都曾被像021 == 17这样的奇怪事实所困扰过。 - Travis Brown
2
Unix权限是八进制的。 - JasonG
3个回答

18

字面量语法已经消失(或正在消失),不太可能以任何形式回来,尽管已经提出了类似 0o700 的替代方案,如此提议

如果你想要更像 2.10 中的编译时字面量,你可以使用宏(这个特定的实现是受 Macrocosm 启发的: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

现在您不需要在运行时解析字符串,任何无效的输入在编译时即可被捕获。


查看我的回答,针对Scala 2.11进行了更新。我没有编辑@Travis Brown的代码,以保持OP所要求的Scala 2.10版本。 - jopasserat
这有助于使用八进制值,但不能处理存储在CSV中的值,我错过了什么吗? - Kiwy

10

如果你想解析八进制,你可以始终使用 BigInt("21",8)


通过将值分配给CONSTANT_VALUE(当然是在“对象”上),您的运行时开销不是问题,并且您对正在处理的内容有一些了解,甚至可能知道“为什么”。 - Richard Sitze

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.")
      }
    }""")
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接