When to use a function which receives a pointer to interface

I was exploring struct and interface and came across an interesting issue where I’ve declared a function which receives a pointer to the interface. I’m not able to call this function either with the value of struct or pointer to struct. Have a look at the following code snippet,

package main

type Intr interface {
    m1()
}

type Student struct {
}

func (s *Student) m1() {
}

func main() {
    s := Student{}
    p := &Student{}

    myfnc(s)         // Not working
    myfnc(p)         // Not working
    myfnc(p.(*Intr)) // Not working
    myfnc(s.(*Intr)) // Not working
}

func myfnc(i *Intr) {
}

So if you look at the main function, we tried passing,

  • struct value
  • struct pointer
  • casting struct pointer to pointer to interface
  • casting struct value to pointer to interface

but none of them worked. I was curious to know when such a type of declaration will be required and how to use it.

3 Likes

https://play.golang.org/p/tM_ZC6dYvM3

3 Likes

My friend wants to ask that pointer to Interface is allowed in go as a param. How would we use that function because none of them work syntactically. Is it a bug?

2 Likes

Hi, @Prithvipal_Singh, There are two classifications of types in Go: concrete types and interface types. Concrete types are everything that is not an interface, including ints, strings, arrays, slices, maps and pointers. The empty interface type, interface{}, is an interface but a pointer to the empty interface, *interface{} is itself a concrete type, just like a slice of empty interfaces, []interface{} is a concrete type.

I adjusted your example to make it compile here: https://play.golang.org/p/cs0RjFf16Sh

As for why you’d ever use a pointer to an interface, I don’t think there are many legitimate use cases.

5 Likes

@skillian Thank you very much for the answer.

I am exploring interfaces, methods, and pointers in details. By curiosity, I tried to create a pointer to the interface. The go compiler did not complain, it allowed me to create it.

Since interfaces are a just contract which may have a list of methods. Any type which defines those methods, implicitly implements the interface. So I tried the above scenario. Thanks to you, you explained very well that pointer to an interface is also a concrete type.

But I still could not understand that what is the need for the pointer to interface? Why would anyone create a pointer to interface? What is the actual use case of it?

1 Like

@Prithvipal_Singh the scenarios would have to be very specific, just like whatever sort of mind-boggling scenario would lead a developer to use a ***bool.

One somewhat real scenario I can think of is unmarshaling:

import (
    "encoding/binary"
    "reflect"
)

var (
    endianness = binary.BigEndian
)

func MyUnmarshal(p []byte, t interface{}) error {
    switch t := t.(type) {
    case *uint32:
        *t = endianness.Uint32(p[:4])
    case *uint64:
        *t = endianness.Uint64(p[:8])
    // ...
    case *interface{}:
        // use the first 4 bytes of p to determine some magic type code
        // and unmarshal into that:
        code := endianness.Uint32(p[:4])
        tp := getReflectTypeForCode(code)
        v := reflect.New(tp).Interface()
        if err := MyUnmarshal(p[4:], v); err != nil {
            return err
        }
        *t = v
    }
    return nil
}
1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.