Trudno mi sformułować pytanie, więc podzielę się obserwacjami licząc na to, że ktoś z Was rzuci mi trochę światła na to, jak to dokładnie działa. Mamy taki kod:
Jak widać GoLand pokazuje, że dwie struktury implementują mój interfejs. Jak się okazuje nie do końca, bo nie mogę przekazać animal
do funkcji rename
, ponieważ jego implementacja metody rename
jest inna - oczekuję pointer receivera. Jeżeli zamienię pointer receivera na value receivera, to wszystko działa i nagle moja struktura już implementuje Renamer
.
Wygląda to trochę tak, jakby struktura miała wpływ na to, jak finalnie wygląda mój interfejs.
Dlaczego to, czy metoda wymaga pointera, czy nie, nie jest narzucone przez interfejs, tylko przez struktury, które go implementują? Czemu nie ma czegoś w stylu:
type Renamer interface {
(r *Renamer) rename(name string)
// albo
(r *struct) rename(name string)
}
Wtedy jasno widać, że ta metoda wymaga wskaźnika do struktury, a nie po prostu struktury. Wydaje mi się, że język powinien mieć jakiś sposób na wymuszenie tego, że jak metoda coś mutuje, to ma mieć pointer receiver inaczej nie spełnia kontraktu. Tym czasem jest to dla mnie mały WTF.