Home > Blockchain >  Ensuring a parameter must be pointer (or interface, which internally a pointer)
Ensuring a parameter must be pointer (or interface, which internally a pointer)

Time:07-08

Sometimes we make a function that like C#'s out in the parameter, just like json.Unmarshal or any kind of unmarshal function.

How in Go compile time (instead of runtime) we can make sure that the variable that being passed is a pointer or an interface?

In runtime I can do something like this:

func mustStructPtr(f interface{}) {
    v := reflect.ValueOf(f)
    if v.Kind() != reflect.Ptr {
        panic(fmt.Errorf("not a pointer: %T", f))
    }
    v = v.Elem() // dereference the pointer
    if v.Kind() != reflect.Struct { // TODO: non null map or slice also ok
        panic(fmt.Errorf("not struct; is %T", f))
    }
}

How to enfoce this on compile time in Golang? so something like this are allowed

var myStruct MyStruct
myFunc(&myStruct) // ok, because pointer
myFunc(myStruct) // <-- not ok, because this cannot receive
var x interface{} = &mystruct
myFunc(x) // ok, because interface to pointer 
x = myStruct
myFunc(x) // <-- not ok, because interface to non pointer

var y map[string]interface{}
myFunc(y) // ok, because map internally a pointer

var z = []myStruct{}
myFunc(&z) // ok, because a pointer

CodePudding user response:

You can't really ensure that. If you really want a pointer I guess you could make your function generic and have it accept *T, but then you still don't know that T is a pointer and it won't work with an interface.

You can catch this with linters (at least for json.Unmarshal) and otherwise, unit testing.

CodePudding user response:

One of the approaches to increase type safety in your case would be to declare a new type and enforce the check on creation.

type PointerOrInterface struct {
    val interface{}
}

func NewPointerOrInterface(val interface{}) PointerOrInterface {
    // check
    return PointerOrInterface{
        val: val,
    }
}
  •  Tags:  
  • go
  • Related