2016-04-16 3 views
0

Как работает следующий код? Я понимаю, что obj1 включает obj2, и поэтому printTest продвигается так, что мы можем вызвать obj1.printTest() вместо того, чтобы называть его, используя obj1.obj2.printTest().Почему этот способ не продвигается в Go?

Что происходит с obj1Selector (я не уверен, что строка даже называется, которая находится перед obj2)? Включает ли obj1Selector obj2? Кто-то сказал мне, что obj1Selector не вставляет obj2, но реализует поле, называемое селектором, которое имеет тип obj2, но что это значит - почему он не внедряется? Почему я не могу назвать oSelector.printTest()?

type obj1 struct { 
    obj2 
} 

type obj1Selector struct { 
    selector obj2 
} 

type obj2 struct { 
} 

func (o obj2) printTest() { 
    fmt.Println("obj2") 
} 

func main() { 
    o := obj1{} 
    o.printTest() 

    oSelector := obj1Selector{} 
    oSelector.selector.printTest() 
    //oSelector.printTest() //Doesn't work 
+0

Я обновил свой ответ в ответ на ваше редактирование. Пожалуйста, проверьте. – desaiparth

+0

«Почему я не могу позвонить oSelector.printTest()?» Потому что функция 'printTest' для значений' obj1Selector' отсутствует. – hobbs

ответ

1

Это называется embedding.

Из спецификации Golang:

Go не обеспечивает типичное, типа с приводом понятия подклассов, но у него есть возможность «одолжить» часть реализации путем встраивания типов в структурах или интерфейсе ,

В случае obj1, это embedding тип obj2, что означает то, что obj2 может сделать, obj1 может сделать. Таким образом, вы можете вызвать printTest прямо на obj1.

В то время как в случае obj1Selector, определяет новое поле под названием selector, который имеет тип obj2, поэтому вы должны вызывать printTest на selector, а не на obj1Selector.

Вы не можете вызвать его непосредственно на obj1Selector, так как этот метод относится к другому полю в этой структуре, а именно: selector.

Это похоже на то, как в java мы можем иметь поле класса с типом другого класса. Поэтому Если вы хотите вызвать функцию, определенную в этом поле, это будет {InstanceOfThatClass}.{fieldName}.{method}.

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