1

In other words - how to write the body of the function assignInterfaceTo, so that the test passes?

type testreq struct {
    V int32
}

func assignInterfaceTo(x, y interface{}) {}

func TestAssignInterfaceTo(t *testing.T) {
    x := &testreq{V: 1}
    y := &testreq{V: 2}
    func(arg interface{}) {
        assignInterfaceTo(arg, y)
    }(x)
    if x.V != y.V {
        t.Fatalf("\nwant: %d\nhave: %d", y.V, x.V)
    }
}

Constraints:

  • it's known that x and y are of same type, if this helps (no need to check if the type is the same)
  • type can be a pointer to arbitrary struct, type of struct is not known in advance, so you can't use switch / type assertion
  • marshal/unmarshal to json or other encodings is not an option

My attempts:

  • reflect.ValueOf(x).Set(reflect.ValueOf(y)):

panic: reflect: reflect.Value.Set using unaddressable value

  • reflect.Copy(reflect.ValueOf(x), reflect.ValueOf(y)):

panic: reflect: call of reflect.Copy on ptr Value

blackgreen
  • 34,072
  • 23
  • 111
  • 129
xakepp35
  • 2,878
  • 7
  • 26
  • 54
  • 5
    `reflect.ValueOf(x).Elem().Set(reflect.ValueOf(y).Elem())` -- iff x and y are pointers to identicaly types. If there's variation between x and y's types you'll need to first define the rules and the implement them using the `reflect` package and plain old programming constructs like `if`, `switch`, etc. – mkopriva Jul 28 '22 at 13:26
  • elem.. thanks. reflect sometimes isnt very obvious when you start working with it ) – xakepp35 Jul 28 '22 at 13:49
  • If types are the same, you could use generics too... – icza Jul 28 '22 at 13:51
  • generics only if you can/want get rid of the anonymous wrapper func, otherwise you still have to type-assert – blackgreen Jul 28 '22 at 14:01
  • @icza this is for code, generated by ge-go-grpc, i doubt that its server would be aware of generics ever.. They cannot even have consistent versioning across their tools in their go.mods, 1.18 will never happen with this project, what to say else.. here func dec is source of the question: https://github.com/grpc/grpc-go/blob/master/server.go#L87 – xakepp35 Jul 29 '22 at 11:04
  • you will run into this problem if you will try to bind their invoker (`grpc.ClientConnInterface`) locally to server (by generated `grpc.ServiceDesc`) in abstract way, in order to simulate client-to-server calls not via network, but locally. for testing, mocking, or proxying calls for example.. http and grpc will marshal/unmarshal in these places, but local variand has a structure ready to use without it – xakepp35 Jul 29 '22 at 11:10

0 Answers0