Композиция против наследования с анонимной структурой - PullRequest
0 голосов
/ 26 октября 2018

Я читал это слайд-шоу , в котором говорится:

var hits struct {
    sync.Mutex
    n int
}

hits.Lock()
hits.n++
hits.Unlock()

Как это работает точно?Похоже, hits не состоит из мьютекс и целое число, но это мьютекс и целое число?

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

См. Синтаксическое представление Go переменной hits:

fmt.Printf("%#v\n", &hits)
// &struct { sync.Mutex; n int }{Mutex:sync.Mutex{state:0, sema:0x0}, n:1}

Когда вы объявляете переменную, она просто инициализирует поля struct с их значениями по умолчанию.

Также,Компилятор автоматически устанавливает имя встроенной структуры в качестве поля.Таким образом, вы также можете получить доступ как:

hits.Mutex.Lock()
hits.Mutex.Unlock()

И у вас есть доступ ко всем методам и экспортируемым полям (если есть) из sync.Mutex.

0 голосов
/ 26 октября 2018

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

Так что вы могли бы так же легко написать:

hits.Mutex.Lock()
hits.n++
hits.Mutex.Unlock()

Когда вы встраиваете тип, поля и методы встроенного типа получают повышенное значение , поэтому вы можете ссылаться на них без указания имени поля (которое является именем встроенного типа), но это просто синтаксический сахар. Цитирование из Спецификация: Селекторы:

Селектор f может обозначать поле или метод f типа T или может ссылаться на поле или метод f вложенного вложенного поля из T.

Помимо продвижения по полю / методу, набор методов типа устройства для внедрения также будет содержать набор методов встроенного типа. Цитирование из Спецификация: Типы конструкций:

Учитывая тип структуры S и определенный тип T, продвигаемые методы включаются в набор методов структуры следующим образом:

  • Если S содержит встроенное поле T, метод устанавливает из S и *S, оба включают повышенные методы с получателем T. Набор методов *S также включает повышенные методы с приемником *T.

  • Если S содержит встроенное поле * T, наборы методов S и * S оба включают повышенные методы с приемником T или * T.

Это не наследование в смысле ООП, а нечто подобное. Это удобно, когда вы хотите реализовать интерфейс: если вы встраиваете тип, который уже реализует интерфейс, то будет и ваш тип структуры. Вы также можете предоставить собственную реализацию некоторых методов, которая дает ощущение переопределения метода, но не следует забывать, что селекторы, обозначающие методы встроенного типа, получат встроенное значение в качестве получателя (а не значение встроенного модуля), и Селекторы, которые обозначают ваши методы, определенные для типа структуры (которые могут или не могут «затенять» метод встроенного типа), получат значение структуры embedder в качестве получателя.

0 голосов
/ 26 октября 2018

Это называется встраиванием, hits состоит из sync.Mutex и int.Это должно быть правдой, так как в Go нет наследования.Это скорее отношение «имеет», а не «является» между членами и структурой.

Прочитайте здесь для более полного объяснения

Цитируетсяпо ссылке

Методы встроенных типов предоставляются бесплатно

Это означает, что вы можете получить к ним доступ как hits.Lock() вместо более длинной формы hits.Mutex.Lock(), потому чтофункция Lock() не является неоднозначной.

...