Gonen I
Gonen I

Reputation: 6127

How to get pointer to interface in GO

I would like to get rid of the variable temp in the following code:

type myinterface interface {
    f1()
}

type a struct {
    val int
}

type b struct {
    mi *myinterface
}

func (a) f1() {

}

    func demo() {

        a1 := a{3}
        var temp myinterface = a1
        b1 := b{&temp}
        fmt.Println(b1)

But if I try to write

b1 := b{&myinterface(a1)}

I get the message

cannot take the address of myinterface(a1) ( undefined )

what is the correct way to do this?

Update:

I did not a pointer to an interface, since an interface can hold a struct or a pointer to a struct, as also detailed in this question:

"<type> is pointer to interface, not interface" confusion

Upvotes: 3

Views: 10888

Answers (2)

Saurav Prakash
Saurav Prakash

Reputation: 1957

Let me know if this is what you are looking for: https://play.golang.org/p/ZGRyIqN7bPR

Full code:

package main

import (
  "fmt"
)

type myinterface interface {
  f1()
}

type a struct {
  val int
}

type b struct {
  mi myinterface
}

func (a) f1() {}


func main() {
  fmt.Println("Hello, playground")

  a1 := &a{3}
  b1 := b{a1}
  fmt.Println(b1)
}

You almost never need a pointer to an interface, since interfaces are just pointers themselves. So just change the struct b to:

 type b struct {
   mi myinterface
 }

Upvotes: 8

icza
icza

Reputation: 418575

myinterface(a1) is a type conversion, it converts a1 to type myinteface.

Type conversion expressions are not addressable, so you cannot take the address of it. What is addressable is listed explicitly in the Spec: Address operators:

The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.

This related answer lists several options how to obtain the address of such expressions: How do I do a literal *int64 in Go?

For example if you use a composite literal to create a slice of type []myinterface and put a1 in it, you can take the address of its first element (which will be of type *myinterface):

b1 := b{&[]myinterface{a1}[0]}

And it will work (try it on the Go Playground):

a1 := a{3}
b1 := b{&[]myinterface{a1}[0]}
fmt.Println(b1)

But know that using pointers to interfaces is very rarely needed, so is a field of type *myinterface really what you want in the first place?

Interface values can be nil, and also nil values (e.g. nil pointers) can also be wrapped in interfaces, so most likely you don't need a pointer to interface. We would have to know your "wider" goal to tell if this is what you really need.

Upvotes: 6

Related Questions