Scala hex literal for bytes

蓝咒 提交于 2019-12-06 04:05:50

You can do this with implicit conversions.

Before:

def f(b: Byte) = println(s"Byte = $b")
f(0x34)
f(0xFF) // compilation error

After:

implicit def int2Byte(i: Int) = i.toByte

def f(b: Byte) = println(s"Byte = $b")
f(0x34)
f(0xFF)

Output:

Byte = 52
Byte = -1

Recall that in Scala we can easily define new ways to interpret arbitrary String literals by adding methods to a special class StringContext using the "pimp-my-library"-pattern. For example, we can add the method b for creating single bytes to StringContext so that we can write down bytes as follows:

val myByte = b"5C"

Here is how it can be implemented:

implicit class SingleByteContext(private val sc: StringContext) {
   def b(args: Any*): Byte = {
     val parts = sc.parts.toList
     assert(
       parts.size == 1 && args.size == 0, 
       "Expected a string literal with exactly one part"
     )
     Integer.parseInt(parts(0), 16).toByte
   }
}

In order to use this new syntax, we have to import the above object into implicit scope. Then we can do this:

/* Examples */ {

  def printByte(b: Byte) = println("%02X".format(b))

  printByte(b"01")
  printByte(b"7F")
  printByte(b"FF")
  printByte(b"80")
}

This will print:

01
7F
FF
80

You can obviously tweak the implementation (e.g. you can rename "b" to "hex" or "x" or "Ox" or something like this).


Note that this technique can be easily extended to deal with entire byte arrays, as described in this answer to a similar question. This would allow you to write down byte arrays without repeating the annoying 0x-prefix, e.g.:

val myBytes = hexBytes"AB,CD,5E,7F,5A,8C,80,BC"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!