Go Метод интерфейса, возвращающий указатель на себя - PullRequest
0 голосов
/ 05 августа 2020

Я работаю с восходящим пакетом в Go, который предоставляет типичный, у которого есть методы, возвращающие указатели на ту же структуру (например, типичный шаблон построителя). Например:

type Dog struct {
    AddCollar() *Dog
}

По некоторым причинам я хотел бы смоделировать эту структуру в определенных сценариях ios (например, для локальной разработки или когда некоторые свойства Dog не существуют et c ...).

Я решил создать общий c интерфейс:

type Animal interface {
    AddCollar() Animal
}

Моим первым побуждением было вернуть Animal здесь, а не *Animal, как указатель к интерфейсу, кажется, не имеет смысла (и, похоже, тоже не работает).

И мой макет просто так, он на самом деле ничего не делает (для сравнения, восходящий поток Dog сделал бы гораздо больше работы которые в этом случае не нужны):

type DogMock struct{}
func (d *DogMock) AddCollar() *DogMock {return d}

Однако после записи и попытки использовать мою фиктивную структуру я получаю:

need method: AddCollar() Animal
have method: AddCollar() *DogMock

Но мой *DogMock объект на самом деле реализует Animal. Обе подписи возвращают одну и ту же ошибку:

type DogMock struct{}
func (d *DogMock) AddCollar() *DogMock {return d}
func (d *DogMock) AddCollar() Animal {return d}

Обратите внимание, что func (d *DogMock) AddCollar() Animal {return d} не кажется решением, потому что я не могу редактировать структуру восходящего потока Dog с помощью метода AddCollar(), который возвращает *Dog, а не Animal.

Есть ли способ указать в моем Animal интерфейсе, чтобы он возвращал указатель на его собственную структуру?

1 Ответ

0 голосов
/ 05 августа 2020

Ваш DogMock просто должен вернуть Animal. Как только DogMock вернет Animal, это будет Animal, и вы сможете вернуть * DogMock как Animal.

package main

import "fmt"

type Animal interface {
    AddCollar() Animal
    AddLeash() Animal
}

type Dog struct {
    HasCollar bool
    HasLeash  bool
}

func (d *Dog) AddCollar() Animal {
    d.HasCollar = true
    return d
}

func (d *Dog) AddLeash() Animal {
    d.HasLeash = true
    return d
}

func main() {
    var a Animal = &Dog{}

    fmt.Printf("%#v\n", a)
    a.AddCollar().AddLeash()
    fmt.Printf("%#v\n", a)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...