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

时间:2018-03-28 11:30:37

标签: 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
    println(String(take!(text[i])))
end

这会产生:

"abc"
""
""

换句话说,第一个索引返回整个字符串"abc"而不是只返回所需的字符'a',其他索引产生空字符串"",因为缓冲区在重置之后被重置第一个take!()功能。

我的下一次尝试有效,但看起来并不复杂:

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缓冲区?

1 个答案:

答案 0 :(得分:2)

您遇到问题的原因是text = fill(IOBuffer(), 3)只在IOBuffer()中调用text,因此julia> all(x->x===text[1], text) true 的所有条目都指向同一个对象。您可以通过运行来检查它:

julia> fill(println("AAA"), 3)
AAA
3-element Array{Void,1}:
 nothing
 nothing
 nothing

或者你可以在运行时看到这个:

println

发现fill只被调用一次 - 然后将其值传递给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 方法。

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

map

julia> map(i->IOBuffer(), 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

实际上,您可以使用invoke类型和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

最后,正如所讨论的here,要记住的一个问题是,理解将为创建的数组的每个条目调用一个函数,但是如果使用宏,它将只被调用一次。以下是链接中详细解释的简短示例:

employer