I am implementing an application layer network protocol which uses JSON in Go.
func ReadMessage(conn net.Conn, returnMessage interface{}) bool {
messageBytes := // read from conn
error := json.Unmarshal(messageBytes, &returnMessage)
if error != nil {
return false
}
return true
}
The function takes a struct as its second parameter where the message is unmarshalled. The function can be called like this:
msg := MessageType1{}
ok := ReadMessage(conn, &msg)
Or without the ampersand (&)
msg := MessageType1{}
ok := ReadMessage(conn, msg)
which will compile, but not do what is should as the struct is passed as a copy, not as a reference and the original msg will remain empty. So I'd like to force passing the struct by reference and catch this error at compile time.
Changing the parameter type to *interface{} will not compile:
cannot use &msg (type *MessageType1) as type *interface {} in function argument:
*interface {} is pointer to interface, not interface
Is there some Go style way of doing this correctly?
There is not a way to do this in the function declaration.
You can use reflection though and panic at runtime when the argument is not a pointer.
However maybe you should consider changing the design of your code. The concrete type of the argument should not matter. It either implements the interface you need or not.
Demo: http://play.golang.org/p/7Dw0EkFzbx
Since Go 1.18 you can do this using generics:
func test[T any](dst *T) {
//Do something with dst
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With