英文:
Copying data hidden by interface
问题
我有一些返回数据的TCP连接。同时,我还有一个表示这些数据的结构。
type Item struct {
A int32
B int32
}
Item
支持 Unpacker
接口
func (item *Item) Unpack(data []int32) {
item.A = data[0]
item.B = data[1]
return
}
type Unpacker interface {
Unpack([]int32)
}
所以我从网络中接收到一些数据,这些数据表示一组项目。现在我想将我的结构传递给函数,并希望返回一个填充有数据的结构切片:
func find(packet [][]int32, responseItem Unpacker) (items []Unpacker) {
items = make([]Unpacker, len(packet))
for i, data := range(packet) {
responseItem.Unpack(data)
items[i] = responseItem
}
return
}
当然,在这种情况下,我得到了一个包含多个相同项目的切片(指向同一项目的指针)。但是我想要不同的项目,而
items[i] = *responseItem
在我的情况下不起作用。
这是playground的链接:http://play.golang.org/p/RP4ryxoG2I
我相信我没有理解Go的工作原理(这是我第一次使用Go)。还有一点需要注意:如果可能的话,我不想在这里使用反射。
英文:
I have got some TCP connection which returns some data for me. Also I have got a structure that represents this data.
type Item struct {
A int32
B int32
}
Item
supports Unpacker
interface
func (item *Item) Unpack(data []int32) {
item.A = data[0]
item.B = data[1]
return
}
type Unpacker interface {
Unpack([]int32)
}
So I receive some data from Network which represents a bunch of items. Now I want to pass my structure to function and I want to get back a slice of structures filled with data:
func find(packet [][]int32, responseItem Unpacker) (items []Unpacker) {
items = make([]Unpacker, len(packet))
for i, data := range(packet) {
responseItem.Unpack(data)
items[i] = responseItem
}
return
}
Of course in this case I have got a slice with a number of identical items (pointers to same item). But I want to get different items and
items[i] = *responseItem
doesn't work in my case.
Here is link to playground: http://play.golang.org/p/RP4ryxoG2I
I believe I didn't understand how Go works (it is my first time with Go). And also good to be noticed: I don't want to use reflection here if it is possible.
答案1
得分: 1
你的find
函数中的Unpacker
使用方式是错误的。你需要在循环中创建新的Item
,将其解包并赋值给切片。你可以通过使find
接受返回Unpacker
的函数来实现这一点。
请参考以下链接:http://play.golang.org/p/rFoa1eoh4A
你的find
函数:
type UnpackerMaker func() (Unpacker)
func find(packet [][]int32, makeUnpacker UnpackerMaker) (items []Unpacker) {
items = make([]Unpacker, len(packet))
for i, data := range(packet) {
unpacker := makeUnpacker()
unpacker.Unpack(data)
items[i] = unpacker
}
return
}
英文:
You've got unpacker backwards. You want to create new Item
in your loop, Unpack into the item and then assign into your slice. You can do this by making find
accept a function returning an Unpacker
.
See the following: http://play.golang.org/p/rFoa1eoh4A
Your find
function:
type UnpackerMaker func() (Unpacker)
func find(packet [][]int32, makeUnpacker UnpackerMaker) (items []Unpacker) {
items = make([]Unpacker, len(packet))
for i, data := range(packet) {
unpacker := makeUnpacker()
unpacker.Unpack(data)
items[i] = unpacker
}
return
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论