2015-02-20 2 views
2

Я читал эту BlogPost http://www.hydrogen18.com/blog/golang-embedding.html и наткнулся на эти линииGoLang иерархия встроенный класс структура

Существует важное различие, чтобы наблюдать здесь. Если myParent является экземпляром Parent, значение myParent не может действовать как Valueable. Вы должны использовать значение & myParent, указатель на экземпляр, чтобы действовать как Valueable. Это связано с тем, что метод Value получает родительский элемент, а не родительский.

Я создал образец https://play.golang.org/p/ojTKZfx97g. Таким образом, вопросы почему вызова метода myparent.Value() работы сам по себе, но не работает, когда вызывается через интерфейс

ответ

1

Ваш callValueable(v Valueable) функция имеет параметр типа Valueable, который является интерфейсом:

type Valueable interface { 
    Value() int64 
} 

Вы можете передать любое значение, которое реализует этот интерфейс. Ваш Parent типа не делает, потому что даже если он имеет метод Value(), что метод имеет указатель приемник:

func (i *Parent) Value() int64{ 
    return i.value 
} 

И согласно спецификации Go Language (Method sets и Interface types) метод набор Parent не включает в себя это метод, только метод, установленный *Parent. Цитируя Spec:

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

Так тип Parent не реализует интерфейс Valueable, но тип *Parent делает его реализовать.

Таким образом, вы можете передать *Parentуказатель к Parent) как Valuable значение для вашего метода, потому что реализует интерфейс. Вы можете легко получить указатель с помощью оператора адреса &:

fmt.Println(callValueable(&myparent)) // This WORKS 
+0

Спасибо icza. Я думаю, что суть проблемы для меня в том, почему golang не вставляет автоматически и для интерфейса, тогда как он делает это при вызове __myparent.value() __. Из-за ограниченности пространства в комментариях я добавляю дополнительную информацию о другом ответе – tabiul

1

По Эффективного Go, если значение адресации затем автоматически вставит & при вызове методы приемника указателя.

Я сделал дальнейшее исследование по этому вопросу и, похоже, понял, что такое адресуемый неправ. Я думал по линии C++, тогда как до тех пор, пока это значение lvalue, оно адресуется.Но, кажется, что в golang не все адресацией, такие как

  • конкретное значение, хранящееся в интерфейсе не адресацией
  • элемент карты не адресацией

Интересный вопрос, то почему конкретный тип интерфейс не адресуется, так что golang может автоматически делать &. Я нашел это https://groups.google.com/forum/#!topic/golang-nuts/-ZoCu5m0kJ4. Я цитирую ответ Стивена Бленкинсопа, который вы можете найти в конце

На одном уровне это потому, что язык говорит так. Но в конечном счете, да, это из-за ограничения на получение указателя для передачи в качестве получателя. Вы не можете принять адрес значения внутри интерфейса, так как его тип может измениться (вы можете назначить другое значение для интерфейса), среди прочих причин. Итак, если вам нужен приемник указателя, сам указатель должен находиться в интерфейсе.

Так как я вижу для интерфейса или карты, так как основной адрес памяти может измениться, может быть, другой поток, поэтому идти не вставлять автоматически & для нас, поскольку он не может гарантировать, адрес памяти будет действовать по всей функции вызывать жизненный цикл.

Смежные вопросы