复制由接口隐藏的数据

huangapple go评论78阅读模式
英文:

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
}

huangapple
  • 本文由 发表于 2013年6月15日 02:55:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/17115433.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定