英文:
how to use golang's zlib?
问题
var buf bytes.Buffer
var outputBuffer [100]byte
b := []byte({"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"],"test":{"prop1":1,"prop2":[1,2,3]}}
)
w := zlib.NewWriter(&buf)
r, _ := zlib.NewReader(&buf)
w.Write(b)
w.Flush()
r.Read(outputBuffer)//cannot use outputBuffer (type [100]byte) as type []byte in function argument
fmt.Println(outputBuffer)
我该怎么做才能解决这个问题?谢谢
英文:
var buf bytes.Buffer
var outputBuffer [100]byte
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"],"test":{"prop1":1,"prop2":[1,2,3]}}`)
w := zlib.NewWriter(&buf)
r, _ := zlib.NewReader(&buf)
w.Write(b)
w.Flush()
r.Read(outputBuffer)//cannot use outputBuffer (type [100]byte) as type []byte in function argument
fmt.Println(outputBuffer)
what can I do to make this right? thanks
答案1
得分: 5
好的,以下是翻译好的部分:
你试图将一个数组用作切片。它期望一个[]byte
,而你给了一个[100]byte
。[]byte
具有动态宽度,而[100]byte
始终是100个字节。数组的大小是其类型的一部分;[1]int
与[2]int
是不同的类型。这就是为什么几乎所有操作都在切片上进行的原因。
但这不是唯一的问题。当你直接在io.Reader
上调用Read
时,它会填充目标切片,但不会扩展它。如果你将输出切片的宽度设为10个字节(make([]byte, 10)
),你将看到的输出将是{"Name":"W
。
但是在这一点上,你可以像标准库文档中所示的那样,直接将os.Stdout
传递给io.Copy
。唯一的区别是我们保留了输出格式的副本,但是...如果输出太大,你不想将其保存在内存中怎么办?这就是为什么io.Copy
接受一个接口的原因:你可以获取压缩数据,并将其未压缩的版本直接写入任何输出流,包括stdout,还包括文件、Unix套接字或网络套接字。
英文:
well you tried to use an array as a slice. It expected a []byte
and you gave it a [100]byte
. A []byte
has a dynamic width, while a [100]byte
is always 100 bytes. An array's size is a part of its type; a [1]int
is a different type from a [2]int
. That's why almost everything operates on slices.
But that's not the only thing. When you call Read
on an io.Reader
directly, it fills in the target slice up to its current width, without expanding it. If you had made your output slice 10 bytes wide (make([]byte, 10)
), the output you would see would be {"Name":"W
.
var in bytes.Buffer
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"],"test":{"prop1":1,"prop2":[1,2,3]}}`)
w := zlib.NewWriter(&in)
w.Write(b)
w.Close()
var out bytes.Buffer
r, _ := zlib.NewReader(&in)
io.Copy(&out, r)
os.Stdout.Write(out.Bytes())
but at this point, you might as well just pass os.Stdout
into io.Copy
, just like they do in the standard library docs. The only difference is we have kept a copy of the output format, but... what if the output is so large that you don't want to hold it in memory? That's why io.Copy
takes an interface: you can take compressed data, and write an uncompressed version of it directly to any output stream, including stdout but also including things like files, unix sockets, or network sockets.
答案2
得分: -3
尝试以下之一:
r.Read([]byte(outputBuffer))
或者
r.Read(outputBuffer[0:100])
我相信这与Go语言中切片(slices)和固定大小数组的概念有关。你可以在这里阅读更多关于这些概念的内容(关于数组和切片的部分):
还有其他方法,例如最初将outputBuffer设置为一个合适的切片而不是固定长度的数组,但是通过上面的指针,你应该能够解决问题。
英文:
Try one of the following:
r.Read([]byte(outputBuffer))
or
r.Read(outputBuffer[0:100])
I believe it has to do with Go's concept of slices versus fixed size arrays. You can read more about these concepts here (the sections about Arrays and Slices):
There are other ways as well, for instance making your outputBuffer a proper slice initially instead of a fixed length array, but with the pointer above you should be able to figure it out.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论