2014-11-27 4 views
20

У меня есть функцияЛитой указатель структуры для интерфейса указатель в Golang

func doStuff(inout *interface{}) { 
    ... 
} 

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

type MyStruct struct { 
    f1 int 
} 

doStuff При вызове

ms := MyStruct{1} 
doStuff(&ms) 

У меня есть

test.go:38: cannot use &ms (type *MyStruct) as type **interface {} in argument to doStuff 

Как я могу бросить &ms быть совместимы с *interface{}?

ответ

40

Нет такой вещи, как «указатель на интерфейс» (технически вы можете использовать ее, но обычно она вам не нужна).

Как видно из «what is the meaning of interface{} in golang?», interface представляет собой контейнер с двумя словами данных:

  • одно слово используется для указания на таблицу методов для базового типа значения,
  • и другое слово используется для : - фактические данные, удерживаемые этим значением.

interface

Так удалить указатель, и doStuff будет работать нормально: данные интерфейса будет &ms, указатель:

func doStuff(inout interface{}) { 
    ... 
} 

См this example:

ms := MyStruct{1} 
doStuff(&ms) 
fmt.Printf("Hello, playground: %v\n", ms) 

Выход:

Hello, playground: {1} 

Как newacct упоминает in the comments:

Передача указателя на интерфейс напрямую работает, потому что если MyStruct соответствует протоколу, то *MyStruct также соответствует протоколу (поскольку набор метод типа А является включен в его набор методов типа указателя).

В этом случае интерфейс представляет собой пустой интерфейс, поэтому он все равно принимает все типы, но все же.

+0

Отлично, вы делаете мой день! – taharqa

+2

Как интерфейсные переменные работают внутри, не имеет отношения к вопросу. Семантически переменная интерфейса содержит копию значения, от которой она была назначена, как и любой другой тип в Go. Под ним реализован неизменный указатель на данные, но это не видно программисту. – newacct

+3

Вы должны объяснить, что передача указателя на интерфейс напрямую работает, потому что если 'MyStruct' соответствует протоколу, то' * MyStruct' также соответствует протоколу (так как набор методов типа входит в набор методов его указателя). В этом случае интерфейс представляет собой пустой интерфейс, поэтому он все равно принимает все типы, но все же. – newacct

Смежные вопросы