Как получить указатель на интерфейс в GO - PullRequest
0 голосов
/ 13 февраля 2019

Я бы хотел избавиться от переменной temp в следующем коде:

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)

Но если я попытаюсь написать

b1 := b{&myinterface(a1)}

, я получу сообщение

не может получить адрес моего интерфейса (a1) (не определено)

Как правильно это сделать?

Обновление:

Я не указывал на интерфейс, поскольку интерфейс может содержать структуру или указатель на структуру, как также подробно описано в этом вопросе:

" - указательинтерфейс, а не интерфейс "путаница

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

myinterface(a1) является типом преобразования , оно преобразует a1 в тип myinteface.

Выражения преобразования типа не адресуемы, поэтому вы не можете получить его адрес.То, что адресуется, явно указано в Spec: Операторы адреса:

Операнд должен быть адресуемый , то есть либо переменная, косвенное указатель,или операция индексации среза;или селектор поля адресуемого структурного операнда;или операция индексации массива адресуемого массива.В качестве исключения из требования адресуемости, x [в выражении &x] также может быть (возможно в скобках) составной литерал .

Этот связанный список ответовНесколько вариантов получения адреса таких выражений: Как сделать литерал * int64 в Go?

Например, если вы используете составной литерал для создания среза типа []myinterface и вставив в него a1, вы можете взять адрес его первого элемента (который будет иметь тип *myinterface):

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

И он будет работать (попробуйте на Go Playground ):

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

Но знайте, что использование указателей на интерфейсы очень редко необходимо, так что поле типа *myinterface действительно то, что вы хотите в первую очередь?

Значения интерфейса могут быть nil, а также значения nil (например, nil указатели) также могут быть заключены в интерфейсы, поэтому, скорее всего, вам не нужен указатель на интерфейс.Нам нужно знать вашу «более широкую» цель, чтобы сказать, действительно ли это то, что вам действительно нужно.

0 голосов
/ 13 февраля 2019

Дайте мне знать, если это то, что вы ищете: https://play.golang.org/p/ZGRyIqN7bPR

Полный код:

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)
}

Вам почти никогда не нужен указатель на интерфейс, так как интерфейсы простосами указатели.Так что просто измените структуру b на:

 type b struct {
   mi myinterface
 }
...