Эта статья возникла из личного публичного аккаунта:TechFlow, оригинальность это не просто, прошу внимания
Сегодняголанг темаВ 10-й статье мы продолжаем рассматривать объектно-ориентированную часть golang.
В прошлой статье мы узнали, как создать структуру, как определить функции для структуры и использовать приемники функций. Сегодня давайте узнаем несколько способов использования самой структуры.
инициализация
в голангеЕсть четыре способа инициализации структуры.
новое ключевое слово
Мы можем создать экземпляр структуры с помощью нового ключевого слова. Этот метод аналогичен другим языкам.указатель на пустую структуру,средиВсе поля заполнены нулевыми значениями, соответствующими их типу. Например, int соответствует 0, float соответствует 0.0, а если это другая структура, то она соответствует nil.
type Point struct {
x int
y int
}
func main() {
var p *Point = new(Point)
fmt.Print(p)
}
Из этого кода мы видим, что новая функцияВозвращает указатель на структуру, а не значение структуры. Как правило, мы редко используем ключевое слово new, а инициализируем его напрямую, добавляя в структуру фигурные скобки.
имя структуры
Вместо использования нового ключевого слова мы используемПередайте имя структуры с фигурными скобкамиспособ инициализации.
Если мы больше не будем заполнять параметры в фигурных скобках, то тоже получим структуру, заполненную нулевыми значениями. Всем свойствам в структуре будет присвоено нулевое значение, соответствующее этому типу.
type Point struct {
x int
y int
}
func main() {
p := Point{}
fmt.Print(p)
}
Если мы хотим инициализировать указатель на структуру, нам просто нужноДобавьте адресный символ & перед именем структуры.. Таким образом, создать указатель структуры можно следующим образом:
func main() {
p := &Point{}
fmt.Print(p)
}
в голангеКлючевые слова для приема адресных символов и объявления указателей такие же, как в языке C., для студентов, знакомых с языком C, это не должно составить труда.
мыПараметры заполнения в фигурных скобках, эти параметры будут заполняться в свойствах структуры по порядку. Чтобы избежать путаницы, мы также можем добавить к значению префикс соответствующего имени свойства.
func main() {
p := &Point{0, 0}
k := &Point{x: 0, y: 10}
fmt.Print(p)
}
наследовать
Основная причина, по которой многим людям не нравится golang, заключается в том, чтоЯ чувствую, что golang кастрировал многие объектно-ориентированные функции.После этого всегда чувствовал себя неудобно при разработке. Среди них больше всего критикуют наследование, я чувствую, что в golang нет наследования, и очень больно писать зависимые структуры.
Я чувствовал это в свое время и раньше, но после того, как я внимательно изучил его недавно, я понял, что ошибался.В golang также есть наследование, но то, как оно реализовано, не совпадает с нашим общим пониманием., с некоторыми сюрпризами. Поэтому, когда мы смотрим на это с ортодоксальной точки зрения, мы всегда будем чувствовать, что это невзрачно и что-то не так. Такое чувство немного похоже на чувство знаменитой семьи, смотрящей на левых в романах о боевых искусствах, но левые не имеют в виду, что они не могут, и есть люди, которые могут сражаться.
В нашем обычном образе, когда мы реализуем наследование, мы должны указать, какой класс является родительским для текущего класса, чтобы базовый компилятор автоматически копировал свойства и методы родительского класса в дочерний класс. С ограничениями ключевых слов, таких как private и public, идеально контролировать, какие методы и свойства могут быть унаследованы, а какие нет.
Возьмем в качестве примера Python, определение наследования в Python очень лаконичное, и реализация, вероятно, будет такой:
class A:
pass
class B(A):
pass
Информация о наследовании добавляется сразу после имени класса, на самом деле это делают большинство основных языков. Но golang нет, что он делает?Он определяет родительский класс как переменную внутри дочернего класса., Строго говоря, это уже не наследование, это странная комбинация, но она работает аналогично наследованию.
Я просто сказал, что это очень утомительно для понимания. Давайте возьмем пример. Например, у нас сейчас есть родительский класс (структура), у которого есть два метода структуры:
type Father struct {
Name string
}
func(entity Father) Hello() {...}
func(entity Father) World() {...}
Теперь мы собираемся создать его подкласс,Вам нужно заполнить структуру Отца и превратить ее в одну из переменных-членов.
type Child struct {
Father
...
}
Имея такой странный подкласс, как нам вызвать метод родительского класса?
ответпозвонить напрямую.
child := Child{}
child.Hello()
Согласно нашему пониманию, поскольку родительский класс является членом дочернего класса, мы должны написать child.Father.Hello(), если мы хотим вызвать метод родительского класса. Но на самом делеgolang сделал для нас соответствующую оптимизацию, мы вызываем метод напрямую, и мы также можем найти метод в родительском классе.
Если мы хотим переопределить метод родительского класса, это не сложно, мы можем сделать это так:
func (entity Child) World() {
entity.Father.World()
...
}
Таким образом, метод World в родительском классе переписывается Child, таким образом завершая переписывание функции родительского класса в наследовании.
Суммировать
На этом введение в инициализацию и наследование структур в golang закончено. Я не знаю, что вы чувствуете после прочтения этого.Мое самое большое чувство, что это не так сложно принять, как когда я впервые увидел это XD.
Говорят, что этот дизайн очень близок к концепции виртуальных базовых классов в C++, но виртуальные базовые классы очень сложны для понимания (например, я не могу их понять), так что многие инженеры C++ автоматически игнорируют его существование. . Напротив, этот дизайн golang гораздо проще понять. Несмотря на то, что это выглядит сложно, понять это несложно.
Сегодняшняя статья здесь, если вам понравилась эта статья, пожалуйста, приходите на волнукачество три, поддержите меня (Подписывайтесь, делайте репосты, лайкайте).
В этой статье используетсяmdniceнабор текста