Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is an Interface a Pointer?

Tags:

go

Suppose I have the following type definitions:

type ICat interface {
  Meow() string
} 

type Cat struct {   
  Name string
}

func (c Cat) Meow() string { 
  return "Meow" 
}

When I perform this operation:

var a Cat
a.Name = "Tom"

A struct of type Cat is allocated in memory and one of its fields gets assigned.

But, if perform the following operation:

var b ICat

What is exactly being allocated in memory? is a Golang Interface just an struct that holds a pointer to another struct? a "Boxed pointer"?.

like image 788
user1275011 Avatar asked Dec 07 '25 14:12

user1275011


2 Answers

An interface holds two things:

  • a pointer to the underlying data
  • the type of that data.

So, when you declare

var b ICat

b contains those two elements.

When you do:

b := Cat{}

b now contains a pointer to a copy of Cat{}, and the fact that the data is a struct Cat.

When you do:

b := &Cat{}

b now contains a copy of the pointer to Cat{}, and the fact that it is a *Cat.

like image 107
Burak Serdar Avatar answered Dec 12 '25 04:12

Burak Serdar


package main

import (
    "fmt"
    "reflect"
)

type Cat struct {
    name string
}

func (c Cat) Meow() {
    fmt.Println("I can meow")
}

type ICat interface {
    Meow()
}

func main() {
    a := Cat{name: "Clara"}
    a.Meow()

    fmt.Printf("a = %v \t type(a) = %T \t &a = %p\n\n", a, a, &a)

    var b ICat
    b = a
    introspectInterface("b", b)

    var c ICat
    c = &a
    introspectInterface("c", c)
}

func introspectInterface(name string, i ICat) {
    iType := reflect.TypeOf(i)
    iValue := reflect.ValueOf(i)

    fmt.Printf("Inside %s - type: %T \t concrete type: %v \t value: %v\n", name, i, iType, iValue)

    if iValue.Kind() == reflect.Ptr {
        ptrValue := iValue.Pointer()
        fmt.Printf("%s points to address (as pointer): %p, pointing to value: %v\n", name, ptrValue, iValue.Elem().Interface())
        fmt.Printf("%s points to the address of &a: %p\n", name, ptrValue)
    }

    fmt.Println()
}

Sample output

I can meow
a = {Clara}      type(a) = main.Cat      &a = 0xc000106050

Inside b - type: main.Cat        concrete type: main.Cat         value: {Clara}

Inside c - type: *main.Cat       concrete type: *main.Cat        value: &{Clara}
c points to address (as pointer): %!p(uintptr=824634794064), pointing to value: {Clara}
c points to the address of &a: %!p(uintptr=824634794064)

https://goplay.tools/snippet/6w4PzNINCSG

Given a variable of interface type, is there a way of getting a pointer to the value stored in the variable?

It is not possible -- Rob Pike

Check https://groups.google.com/g/golang-nuts/c/vPHiJwxVN98

Refer Take address of value inside an interface for more details

like image 21
reddy nishanth Avatar answered Dec 12 '25 06:12

reddy nishanth



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!