Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force passing parameter as a pointer in Go?

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?

like image 900
juke Avatar asked Oct 16 '25 23:10

juke


2 Answers

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

like image 190
Agis Avatar answered Oct 19 '25 12:10

Agis


Since Go 1.18 you can do this using generics:

func test[T any](dst *T) {
  //Do something with dst
}
like image 22
Fenistil Avatar answered Oct 19 '25 12:10

Fenistil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!