Io 在Julia中设置多个I/O缓冲区的最佳方法是什么?

Io 在Julia中设置多个I/O缓冲区的最佳方法是什么?,io,buffer,julia,Io,Buffer,Julia,我正在试验处理Julia中的长文本字符串(例如书籍长度)的不同方法。具体来说,我正在研究转置密码,并一直在使用(1)字符串串联,(2)数组和(3)I/O缓冲区测试速度和内存使用情况。在最后一种情况下,我需要能够将单个字符“打印”到不同的、可索引的I/O缓冲区。我的第一次(简化)尝试如下: text = fill(IOBuffer(), 3) print(text[1], 'a') print(text[2], 'b') print(text[3], 'c') for i in 1:3 p

我正在试验处理Julia中的长文本字符串(例如书籍长度)的不同方法。具体来说,我正在研究转置密码,并一直在使用(1)字符串串联,(2)数组和(3)I/O缓冲区测试速度和内存使用情况。在最后一种情况下,我需要能够将单个字符“打印”到不同的、可索引的I/O缓冲区。我的第一次(简化)尝试如下:

text = fill(IOBuffer(), 3)
print(text[1], 'a')
print(text[2], 'b')
print(text[3], 'c')
for i in 1:3
    println(String(take!(text[i])))
end
这将产生:

"abc"
""
""
换句话说,第一个索引返回整个字符串
“abc”
,而不仅仅是所需的字符
'a'
,而其他索引生成空字符串
,因为缓冲区在第一次
执行后被重置!()
函数

我的下一次尝试成功了,但似乎并不十分复杂:

text = Vector(3)
for i in 1:3
    text[i] = IOBuffer()
end
print(text[1], 'a')
print(text[2], 'b')
print(text[3], 'c')
for i in 1:3
    println(String(take!(text[i])))
end
这将产生所需的输出:

"a"
"b"
"c"

我仍然不能完全确定为什么第一种方法失败,第二种方法可以工作,但是有人知道更好的方法来设置多个I/O缓冲区,可以使用索引写入吗?

问题的原因是在
text=fill(IOBuffer(),3)
调用
IOBuffer()
只计算一次,因此
文本的所有条目都指向同一对象。您可以通过运行以下命令进行检查:

julia> all(x->x===text[1], text)
true
或者,您可以在运行时看到:

julia> fill(println("AAA"), 3)
AAA
3-element Array{Void,1}:
 nothing
 nothing
 nothing
在将其值传递给
fill
方法之前,只调用了一次
println

解决这个问题的最简单方法是使用理解:

julia> text = [IOBuffer() for i in 1:3]
3-element Array{Base.AbstractIOBuffer{Array{UInt8,1}},1}:
 IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)
 IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)
 IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)

julia> map(x->x===text[1], text)
3-element Array{Bool,1}:
  true
 false
 false
映射
(稍微不干净):

实际上,您可以使用
IOBuffer
类型填充数组,并
调用它们(这不是一种推荐的方法,但向您展示了区别):

最后,如前所述,需要记住的一点是,理解将为所创建数组的每个条目调用一个函数,但如果使用宏,它将只被调用一次。下面是链接中详细说明的一个简短示例:

julia> rx = [Regex("a") for i in 1:3]
3-element Array{Regex,1}:
 r"a"
 r"a"
 r"a"

julia> map(x->x===rx[1], rx)
3-element Array{Bool,1}:
  true
 false
 false

julia> rx = [r"a" for i in 1:3]
3-element Array{Regex,1}:
 r"a"
 r"a"
 r"a"

julia> map(x->x===rx[1], rx)
3-element Array{Bool,1}:
 true
 true
 true

理解和地图解决方案都很好地工作,我将使用前者,因为前者更整洁。谢谢
julia> text = invoke.(fill(IOBuffer, 3), [Tuple{}])
3-element Array{Base.AbstractIOBuffer{Array{UInt8,1}},1}:
 IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)
 IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)
 IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)

julia> map(x->x===text[1], text)
3-element Array{Bool,1}:
  true
 false
 false
julia> rx = [Regex("a") for i in 1:3]
3-element Array{Regex,1}:
 r"a"
 r"a"
 r"a"

julia> map(x->x===rx[1], rx)
3-element Array{Bool,1}:
  true
 false
 false

julia> rx = [r"a" for i in 1:3]
3-element Array{Regex,1}:
 r"a"
 r"a"
 r"a"

julia> map(x->x===rx[1], rx)
3-element Array{Bool,1}:
 true
 true
 true