我正试图将二进制数据复制到一个数组中,结果出乎我意料。我把它简化为一个较小的问题来证明它
b: #{0102030405060708}
c: array (length? b)
repeat num (length? b) [
print [
{Setting location}
num
{to value of}
to-binary reduce [(pick b num)]
]
poke c num (to-binary reduce [(pick b num)])
]
这导致:
Setting location 1 to value of #{01}
Setting location 2 to value of #{02}
Setting location 3 to value of #{03}
Setting location 4 to value of #{04}
Setting location 5 to value of #{05}
Setting location 6 to value of #{06}
Setting location 7 to value of #{07}
Setting location 8 to value of #{08}
== #{08}
>> c
== [#{08} #{08} #{08} #{08} #{08} #{08} #{08} #{08}]
我可以看到我正在返回带有重复块的==#{08}
,但我不知道它是从哪里来的。我检查了trace on
,似乎poke语句在重复的每一步都设置了块的所有元素。这似乎是一个指针问题,我可以用copy
解决它。有人能告诉我发生了什么吗?
更多测试:
>> to-binary reduce [pick b 1]
== #{01}
>> poke c 1 to-binary reduce [pick b 1]
== #{01}
>> c
== [#{01} #{01} #{01} #{01} #{01} #{01} #{01} #{01}]
>> poke c 2 #{02}
== #{02}
>> c
== [#{01} #{02} #{01} #{01} #{01} #{01} #{01} #{01}]
>> u: to-binary reduce [pick b 4]
== #{04}
>> poke c 4 u
== #{04}
>> c
== [#{04} #{02} #{04} #{04} #{04} #{04} #{04} #{04}]
对Ladislavs答案的回应:
谢谢你对这个bug的回答。
第一个例子给出的结果与我预期的不同。二进制元素的每个长度为8,而我对长度1感兴趣(因此使用了to-binary
的块参数)
>> c
== [#{0000000000000001} #{0000000000000002} #{0000000000000003} #{0000000000000004} #{0000000000000005} #{0000000000000006} #{0000000000000007} #{0000000000000008}]
第二种方法是将c: array (length? b)
替换为c: copy []
您遇到了一个已知的错误。(修正拉请求已经提交,AFAIK)解决方法是永远不要将块用作to二进制函数的参数。以下代码应该有效:
b: #{0102030405060708}
c: array (length? b)
repeat num (length? b) [
print [
{Setting location}
num
{to value of}
to-binary pick b num
]
poke c num to-binary pick b num
]
然而,对我来说,整个代码看起来过于复杂,我宁愿使用来实现您的目标
b: #{0102030405060708}
c: make block! length? b
repeat num (length? b) [
print [
{Setting location}
num
{to value of}
copy/part at b num 1
]
append c copy/part at b num 1
]
如果你只想从一个整数创建一个短(长度为1)的二进制,你可以使用这个公式:
append copy #{} 255