Можно ли заставить его работать без использования интерфейса? - PullRequest
0 голосов
/ 31 января 2020

Почему при добавлении типа Pet []interface{Name()} работает следующее, а при добавлении типа Pet []string - нет? Можно ли заставить его работать без с помощью интерфейса?

package main

import "fmt"

type Pet []string // cannot use Cat("Puss") (type Cat) as type string in array or slice literal
// type Pet []interface{Name()} // prt Fluffy

type Cat string

func (c Cat) Name() {
    fmt.Println(c)
}

func main() {
    p := Pet{Cat("Whiskers"), Cat("Fluffy")} 
    p1 := p[1]
    p1.Name() 
}

./oo3.go:15:14: cannot use Cat("Whiskers") (type Cat) as type string in array or slice literal
./oo3.go:15:31: cannot use Cat("Fluffy") (type Cat) as type string in array or slice literal
./oo3.go:17:4: p1.Name undefined (type string has no field or method Name)

1 Ответ

5 голосов
/ 31 января 2020

Тип Pet, объявленный как []string, не может быть инициализирован значением типа Cat, поскольку Cat и string - это разные типы. Вот как работает система типа Go. Когда вы определяете новый тип как type name otherType, name становится совершенно новым типом с той же структурой памяти, что и базовый тип. Например, новый тип не будет иметь методов, определенных для otherType. Однако вы можете преобразовать Cat в строку:

    p := Pet{string(Cat("Whiskers")), string(Cat("Fluffy"))} 

Тогда Pet все еще будет массивом строк.

Когда вы определите Pet как массив интерфейсов с помощью метода Name, тогда Cat теперь можно использовать для инициализации элементов Pet, поскольку Cat реализует метод Name.

Короче говоря: Pet как []string содержит только строковые значения. Pet как []interface{Name{}} содержит любое значение, которое реализует метод Name. Если вам нужно вызвать метод Name для Pet элементов, то вы должны сделать это с помощью интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...