О реализации метода для интерфейса - PullRequest
0 голосов
/ 10 мая 2018

Кто-нибудь может объяснить, почему работает вызов a.Abs ()? На мой взгляд, 'a' - это переменная типа * Vertex, но тип * Vertex не реализует метод Abs.

package main

import (
    "fmt"
    "math"
)

type Abser interface {
    Abs() float64
}

func main() {
    var a Abser

    v := Vertex{3, 4}
    a = &v // a *Vertex implements Abser
    // In the following line, v is a *Vertex (not Vertex)
    // and does NOT implement Abser, but why does this calling work?
    fmt.Println(a.Abs())

}

type Vertex struct {
    X, Y float64
}

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

1 Ответ

0 голосов
/ 10 мая 2018

Из тонкой спецификации :

Наборы методов
[...] Набор методов соответствующего типа указателя * Tнабор всех методов, объявленных с помощью приемника * T или T (то есть он также содержит набор методов T).[...]

Ваша Abs функция находится в наборах методов как Vertex, так и *Vertex, поэтому *Vertex - это Abser, как и Vertex.

Другие связанные разделы:

В общем, указатели автоматически разыменовываются, когда это возможно, поэтому вы можете сказать x.M() и x.V, не беспокоясь о том, является ли x указателем, и нет необходимости в C -> или разыменование вручную (например, (*x).M() или (*x).V).

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