考虑以下内容:
>> bin: to-binary {Rebol}
== #{5265626F6C}
>> parse/all bin [s: to end]
== true
我期望s
已经捕获了二进制序列的头,并且类型为binary !在Rebol 3中是这样的:
>> type? s
== binary!
>> s == bin
== true
在Rebol 2中,似乎parse必须将数据转换为字符串(或至少将二进制"成像"为字符串)!在引擎盖下,不比较相等)
>> type? s
== string!
>> s == bin
== false
因为Rebol 2不是Unicode,二进制字节串和字符串基本上是等价的。但是对于Rebol 3的Unicode,我猜测如果你写:
,你可能会得到非常不同的行为:parse/all to-string bin [s: to end]
因为它会开始将多个字节序列解释为字符串编码,如果您真正想要的是未解释的字节,这将不起作用。: - (
如果你想写的代码在Rebol 2或Rebol 3中都能很好地解析二进制!你会如何解决这个问题?(理想情况下让Rebol 2更像3)
事实上,Rebol 2实际上只是将数据"成像"为STRING!不要复制它,注意下面的
>> bin: to-binary {Rebol}
== #{5265626F6C}
>> parse bin [s: (clear s)]
== true
>> s
== ""
>> bin
== #{}
这是因为Rebol 2有可用于将字符串数据混叠为二进制数据的例程,反之亦然:as - binary和as - string。与它们的TO-BINARY和TO-STRING变体不同,它们实际上并不复制数据。
这里有一个你(嗯,嗯,我)可以尝试的想法…创建一个兼容函数(我们称之为bin-pos
):
bin-pos: func [pos [binary! string!]] [
return either string? pos [
;; we must be using r2, image the parse position back to binary
as-binary pos
] [
;; just a no-op in r3, binary parse input yields binary parse positions
pos
]
]
所以在上面的例子中,对于Rebol 2,正确的事情发生了,如果你在任何地方使用s
,你代替bin-pos s
:
>> type? (bin-pos s)
== binary!
>> (bin-pos s) == bin
== true
对于使用COPY方言单词并生成新字符串的情况,同样的技术将起作用…但也许应该使用不同的包装器名称。bin-capture
?
您可以在规则中添加一个解析操作,以确保捕获的数据是binary!
:
>> bin: to binary! {Rebol}
>> parse/all bin [s: to end (s: to binary! s)]
>> type? s
== binary!
出于文档目的,您可以将此转换封装在ensure-binary
帮助器中。
copy
,您也可以使用这种方法。)