@Artem0071
Безработный mr. Junior

Почему нельзя вернуть так структуру?

Почему в функции, которая должна вернуть интерфейс, нельзя вернуть структуру, реализующую сам этот интерфейс? Или можно как-то по-другому? Или что-то вообще не так? Я как то запутался..

cannot use a (type []a) as type []IA in return argument


Вот код: play
package main

type IA interface {
	GetName() string
}

type a struct {

}

func (r a) GetName() string {
	return "name"
}


func main() {
	getA()
}

func getA() []IA {
	var a = make([]a, 10)
	return a
}
  • Вопрос задан
  • 618 просмотров
Решения вопроса 3
EvgenyMamonov
@EvgenyMamonov Куратор тега Go
Senior software developer, system architect
В реальной жизни, скорее всего, задачу придёться решать немного иначе.
Обычно вам приходят данные в виде структур, например, когда вы извлекаете данные из базы.
В момент получения данных вам нужно просто заполнить слайс интерфейсов этими структурами (которые реализуют методы интерфейса)

Сделал пример того, как задача может быть решена

https://play.golang.org/p/RKrCLIqakXg

package main

import "fmt"

// объявляем интерфейс
type Profile interface {
	GetFullName() string
}

// структура данных, которая будет реализовывать интерфейс Profile
type User struct {
    Name string
    LastName string
}

// реализация метода интерфейса Profile
func (u User) GetFullName() string {
	return u.Name + ` ` + u.LastName
}

// пример функции, которая извлекает/формирует данные и возвращает слайс интерфейсов
func getProfiles() []Profile {
        // создаём слайс интерфейсов
	var result = make([]Profile, 10)

	for i := 0; i<10; i++ {
	    // но заполняем слайс структурами, которые реализуют этот интерфейс
	    result[i] = User{
	        Name: fmt.Sprintf("Name%d", i),
	        LastName: fmt.Sprintf("LastName%d", i),
	    }
	}

	return result
}

// пример функции, которая работает со слайсом интерфейсов.
func printProfiles(profiles []Profile) {
    for _, profile := range profiles {
        fmt.Println(profile.GetFullName())
    }
}

func main() {
	printProfiles(getProfiles())
}
Ответ написан
Комментировать
Потому что проверка на удовлетворение интерфейсу производится над одним значением, а не над коллекциями.
Если вы возвращаете из функции типа []IA, то и переменная, которую вы возвращаете, должна быть типа []IA. Но никто вам не помешает положить в этот массив элементы типа a.

https://play.golang.org/p/t7VMS0KQDas
func getA() []IA {
	var arr = make([]IA, 10)
	arr[0] = a{}
	return arr
}
Ответ написан
Комментировать
@deliro
Почему в функции, которая должна вернуть интерфейс, нельзя вернуть структуру, реализующую сам этот интерфейс?

Конечно можно: https://play.golang.org/p/ximR1mGUaAg

Но то, что ты показываешь в коде, называется ковариантностью, в которую го не умеет. Это проблема языка. Решается или вот так: https://play.golang.org/p/RrHMV2neUvp или явным кастом, в зависимости от случая.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы