以下 Python 语句的等效 Scala 是什么?看起来它正在使用 unsigned long 或其他东西(Scala 没有)。
size = pack('!L', len(someString))
此语句没有精确的一对一映射,但您可以接近。
在 Scala 中,您通常不会将二进制数据存储在字符串pack
中。相反,您将其存储在Array[Byte]
.
Scala 本身没有为此提供任何库,但 Java 有,您可以在 Scala 代码中使用它们。
val out = new java.io.ByteArrayOutputStream()
val writer = new java.io.DataOutputStream(out)
writer.writeInt(someString.length)
writer.close()
val data = out.toByteArray
关于为什么会这样,有几点需要注意:
DataOutputStream
以大端顺序写入,这与您!
在 Python 代码中的使用相匹配。如果您以小端顺序编写,则必须使用DataOutputStream 的小端实现。pack
方法写入一个 long 为 4 个字节,writeInt
与DataOutputStream
. writeLong
将与 中的long long
(q
或Q
)相同pack
。根据 python 文档,该pack
方法执行以下操作:
Return a string containing the values v1, v2, ... packed according to the given format. The arguments must match the values required by the format exactly.
!
意思是大端,意思L
是Unsigned Long
。
没错,Scala 没有无符号数字。但这并不重要,因为它只意味着传入的值必须在无符号长整数的范围内。
看到这个输出:
>>> pack("!L", 2442442424)
'\x91\x94\xb6\xb8'
>>> pack("!l", 2442442424)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: 'l' format requires -2147483648 <= number <= 2147483647
我认为 scala 或 java 的 stdlib 中没有等效的方法,但编写一个应该不难。您只需要将您的数字转换为大端,然后将其转换为字节数组。
Scala 在其标准库中没有这样的东西:你应该看看 Java。
顺便说一句,你不能这样做String
:你需要将这些方法应用于Array[Byte]
. 问题String
在于它是由 UTF-16 字符组成的,所以一些字节序列是非法字符串。