Go имеет structs вместо class es, как мы видим в других языках. Структуры в основном охватывают некоторые поля внутри.

package main
  ​
  import (
      "fmt"
  )
  ​
  type School struct {
      Name string
      Country string
      NumOfStudents int
  }
  ​
  func main() {
      school := School{"ABC Primary School", "Canada", 5000}
      fmt.Println(school.Name)
  }

Выше у нас есть school как структура, которая содержит Name, Address и NumOfStudents.

Чтобы получить доступ к любому из полей в структуре, мы используем оператор ., например. school.Name.

Мы можем инициализировать struct несколькими способами.

func main() {
      // initializing according to the order of fields without specifying field names
      school := School{"ABC Primary School", "Canada", 5000}
      fmt.Println(school.Name)
      
      // initializing with field names and in random order
      school2 := School{Name: "XYZ Primary School", NumOfStudents: 2000, Country: "America"}
      fmt.Println(school2.NumOfStudents)
      
      // initializing only some struct fields
      school3 := School{Name:"Jingle Bells Secondary School"}
      fmt.Println(school3.Name)
  }

Приведенное выше выведет следующее:

ABC Primary School
2000
Jingle Bells Secondary School

Примечание

Название полей в структуре, начинающееся с заглавных букв, позволяет нам свободно обращаться к ним. Читайте дальше, чтобы узнать, как ограничить доступ.

Анонимные члены структуры

В некотором смысле наследование может осуществляться с использованием анонимных членов структуры.

type Lab struct {
      numOfEquipment int 
  }
   
  type School struct {
      Lab //anonymous field
      numOfStudents int 
  }
  ​
  func main() {
      // initialise a school with 300 students and a lab with 10 equipment 
      school := School{Lab{10}, 300}
      fmt.Println(school.numOfEquipment)
  }

Мы достигаем наследования через композицию. Это означает, что school.numOfEquipment является допустимым доступом, хотя School не содержит этого поля напрямую.

Если две структуры, из которых вы «вставляете», имеют одинаковое имя свойства, нам нужно указать «промежуточный» тип структуры, а затем имя свойства.

type Lab struct {
      numOfEquipment int
  }
  ​
  type SportsRoom struct {
      numOfEquipment int
  }
  ​
  type School struct {
      Lab
      SportsRoom
  }
  ​
  func main() {
      school := School{Lab{3}, SportsRoom{4} }
      fmt.Println(school.Lab.numOfEquipment + school.SportsRoom.numOfEquipment)
  }

Методы структур

У нас могут быть приемники указателей для структур, т.е. тип получателя имеет синтаксис *T, где T — тип структуры.

package main
  ​
  import (
      "fmt"
  )
  ​
  type Circle struct {
      radius int
  }
  ​
  // pointer receiver method
  func increaseRadiusByOne(c *Circle) {
      c.radius += 1
  }
  ​
  // value receiver method
  func increaseRadiusByTwo(c Circle) {
      c.radius += 2
  }
  ​
  func main() {
      c := Circle{2}
      increaseRadiusByOne(&c) // passing the reference to c
      fmt.Println(c.radius)   // prints 3
      
      increaseRadiusByTwo(c)  // passing a copy of c
      fmt.Println(c.radius)   // still prints 3
  }

Использование получателя указателя изменит исходную структуру, поскольку она получает ссылку на сам фактический объект. В приведенном выше примере increaseRadiusByOne(&c) передает фактический объект c, определенный в методе main. Таким образом, фактический радиус изменяется.

При использовании получателя значения получается копия структуры. При изменении свойств структуры в нем не будет никаких изменений в исходной структуре. В приведенном выше примере increaseRadiusByTwo(c) передает копию c, и изменение копии c не влияет на фактический c, определенный в методе main.Первоначально опубликовано на https://rightfrombasics.com 29 декабря 2018 г.

Первоначально опубликовано на https://rightfrombasics.com 29 декабря 2018 г.