Функция выдает ошибку при передаче указателя на интерфейс?

Вот с чем я столкнулся, и я не могу понять, почему ошибка:

package main

import (
    "fmt"
)

// define a basic interface
type I interface {
    get_name() string
}

// define a struct that implements the "I" interface
type Foo struct {
    Name string
}

func (f *Foo) get_name() string {
    return f.Name
}

// define two print functions:
// the first function accepts *I. this throws the error
// changing from *I to I solves the problem
func print_item1(item *I) {
    fmt.Printf("%s\n", item.get_name())
}

// the second function accepts *Foo. works well
func print_item2(item *Foo) {
    fmt.Printf("%s\n", item.get_name())
}

func main() {
    print_item1(&Foo{"X"})
    print_item2(&Foo{"Y"})
}

Две идентичные функции принимают один аргумент: указатель либо на интерфейс, либо на структуру, реализующую его. Первый, который принимает указатель на интерфейс, не компилируется с ошибкой item.get_name undefined (type *I is pointer to interface, not interface).
Переход с *I на I решает проблему.

Я хотел бы знать, ПОЧЕМУ разница? Первая функция очень распространена, поскольку позволяет использовать одну функцию с различными структурами, если они реализуют интерфейс I.

Кроме того, почему функция компилируется, когда она определена для приема I, но фактически получает указатель (&Foo{})? Должна ли функция ожидать чего-то вроде Foo{} (т.е. НЕ указателя)?

stackoverflow.com/a/44372954/2664120 может вам поможет этот ответ?
Nordiii 13.12.2018 14:10

Нет причин использовать указатель на интерфейс. Просто удалите их все, и проблем не будет.

JimB 13.12.2018 14:10
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
2
2
93
1

Ответы 1

Быстрое решение этой проблемы - сделать так, чтобы print_item1 просто принимал I, а не указатель на I.

func print_item1(item I)

Причина этого в том, что *Foo удовлетворяет интерфейсу I, но помните, что *Foo не является *I.

Я настоятельно рекомендую прочитать Рассказ Кокса о реализации интерфейсов

Причина правильная, я бы не стал предлагать принимать I, не зная контекста.

robertodecurnex 28.07.2021 14:43

Другие вопросы по теме