Skip to content

Commit

Permalink
fix (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
guonaihong authored Jun 8, 2023
1 parent 8beb74a commit 0527e78
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 8 deletions.
24 changes: 16 additions & 8 deletions pcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,22 @@ func pcopyInner(dst, src interface{}, opt options) error {

if opt.preheat {
all = newAllFieldFunc()
// if dstValue.Type().Kind() != reflect.Struct && srcValue.Type().Kind() != reflect.Struct {
// saveToCache(dstSrcType{
// dst: dstValue.Type(),
// src: srcValue.Type(),
// },
// all)
// }
// 如果顶层对象是结构体,肯定会有预热结构
// 但是是其它类型可能没有预热结构, 所以这里要判断一下
if dstValue.Type().Kind() != reflect.Struct && srcValue.Type().Kind() != reflect.Struct {
saveToCache(dstSrcType{
dst: dstValue.Type(),
src: srcValue.Type(),
},
all)
}
}

// 按道理已经预热过的类型, 不会走到这里
// 但这里有个特殊情况,比如多级不对称指针。为了支持这种情况,就不报错了
// if opt.usePreheat {
// return errors.New("usePreheat must be used with preheat")
// }
}

d := pcopy{
Expand Down Expand Up @@ -490,7 +498,7 @@ func (d *pcopy) cpyDefault(dst, src reflect.Value, dstBase, srcBase unsafe.Point
}

func (d *pcopy) pcopy(dst, src reflect.Value, dstBase, srcBase unsafe.Pointer, of offsetAndFunc, all *allFieldFunc) error {
// 预热的时间一定要绕开这个判断, 默认src都有值
// 预热的时候一定要绕开这个判断, 不管src有值没值都要继续往下走
// 寻找和dst匹配的字段
if !(d.preheat || d.usePreheat) {
if src.IsZero() {
Expand Down
80 changes: 80 additions & 0 deletions pcopy_bug_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package pcopy

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
)

type LetterInbox struct {
ID int32
FromRid int64
ToRid int64
Msg string
}

var resp = []LetterInbox{
{
ID: 1,
FromRid: 3,
ToRid: 4,
Msg: "ww,",
},
}

type ReadLetterResponseItem struct {
Msg string
}

type ReadLetterResponse struct {
List []*ReadLetterResponseItem `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"`
}

func Test_ReadLetter(t *testing.T) {
var rv ReadLetterResponse
err := Preheat(&rv.List, &resp)
assert.NoError(t, err)
err = Copy(&rv.List, &resp, WithUsePreheat())
assert.NoError(t, err)

fmt.Printf("%#v\n", rv.List)
fmt.Printf("%#v\n", rv.List[0])
// fmt.Printf("%#v\n", rv.List[1])
}

func Test_ReadLetter2(t *testing.T) {
var rv ReadLetterResponse
err := Preheat(&rv.List, &LetterInbox{})
assert.NoError(t, err)

resp2 := []LetterInbox{
{
ID: 1,
FromRid: 3,
ToRid: 4,
Msg: "hello",
},
}
err = Copy(&rv.List, &resp2, WithUsePreheat())
assert.NoError(t, err)

assert.Equal(t, rv.List[0].Msg, "hello")
}

func Test_ReadLetter3(t *testing.T) {
var rv ReadLetterResponse

resp2 := []LetterInbox{
{
ID: 1,
FromRid: 3,
ToRid: 4,
Msg: "hello",
},
}
err := Copy(&rv.List, &resp2)
assert.NoError(t, err)

assert.Equal(t, rv.List[0].Msg, "hello")
}

0 comments on commit 0527e78

Please sign in to comment.