Как передать массив структур, которые содержат basi c one | Полиморфизм в Golang - PullRequest
0 голосов
/ 03 мая 2020

Я изучаю Golang и у меня есть вопрос ниже.

У нас есть одна структура basi c и еще две, которые содержат basi c. Можно ли написать забавный c, который ожидает массив структуры basi c, но назовем это забавным c с предоставлением двух других? См. Пример ниже.

// Pathable provide path property
type Pathable struct {
    path string
}

// File sturcture
type File struct {
    name string
    Pathable
}

// Directory structure
type Directory struct {
    name        string
    files       []File
    directories []Directory
    Pathable
}

// Detect if provided directories contain specified path
func ifPathAlreadyExist(entities []Pathable, path string) bool {
    for _, entity := range entities {
        if entity.path == path {
            return true
        }
    }
    return false
}

func main() {
    pathables := []File{
        File{
            name: "some_file.txt",
            Pathable: Pathable{
                path: "test_path/to/file",
            },
        },
    }

    localPath := "some/path"
    if ifPathAlreadyExist(pathables, localPath) {
        fmt.Println("Exist")
    }
}

Приведенный выше код генерирует исключение cannot use pathables (variable of type []File) as []Pathable value in argument to ifPathAlreadyExist при вызове ifPathAlreadyExist.

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

Итак, на самом деле мой вопрос заключается в том, как правильно реализовать ifPathAlreadyExist, чтобы избежать дублирования этого метода для каждой структуры, которая содержит структуру Pathable внутри?

Спасибо за внимание и помощь!

Ответы [ 2 ]

1 голос
/ 03 мая 2020

Ваш пример идеально подходит для go interface. Go не дает вам возможности объединять сущности по ее внутренностям, вместо этого вы можете делать это по их поведению.
Таким образом, в вашем случае есть только три различных структуры, и встраивание Pathable в File не делает его Pathable, хотя File унаследует Pathable методы.

1 голос
/ 03 мая 2020

Для этого вы можете использовать интерфейсы . Вот пример :

type Pathable interface {
    GetPath() (path string)
}

type PathableImpl struct {
    path string
}

func (p *PathableImpl) GetPath() string {
    return p.path
}

type File struct {
    name string
    PathableImpl
}

func printPaths(entities []Pathable) {
    for _, entity := range entities {
        fmt.Println(entity.GetPath())
    }
}

func main() {
    printPaths(
        []Pathable{
            &PathableImpl{path:"/pathableImpl"}, 
            &File{name: "file", PathableImpl: PathableImpl{path:"/file"}}
        }
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...