Изучение структур в Go
Структуры — это способ структурировать и использовать данные. Это позволяет нам группировать данные. В этой статье мы увидим, как их объявить и использовать в Go.
Определение структуры в Go
Чтобы использовать структуру, мы объявляем тип структуры, которую собираемся использовать. В приведенном ниже коде показано, как определить тип структуры с помощью ключевого слова type .
package main import ( "fmt" ) type Fruit struct { name string } // to define a struct type use // type structname struct { // field1 type1 // field2 type2 // ... // } func main() { }
Объявление структурных переменных
Мы увидим, как объявить структурную переменную. Это действительно просто, как показано ниже.
var variablename structname // declare a struct variable
Что такое структура с нулевым значением?
Если структура объявлена, но ей не присвоено никакого значения, тогда это структура с нулевым значением. Это означает, что все поля будут принимать соответствующие нулевые значения из своих типов.
package main import ( "fmt" ) type Fruit struct { name string } func main() { var apple Fruit fmt.Println(apple) // prints {} }
Создание и инициализация структуры в Golang
Теперь мы создадим структуры и инициализируем их значениями. Есть несколько способов сделать это.
1. Использование синтаксиса структурного литерала
Синтаксис структурного литерала — это просто присвоение значений при объявлении, и это действительно просто.
package main import ( "fmt" ) type Fruit struct { name string } func main() { var apple = Fruit{"Apple"} // struct literal syntax fmt.Println(apple) // prints {Apple} }
2. Использование ключевого слова new
Мы можем использовать ключевое слово new при объявлении структуры. Затем мы можем присвоить значения, используя точечную запись для его инициализации.
package main import ( "fmt" ) type Fruit struct { name string } func main() { var banana = new(Fruit) banana.name = "Banana" fmt.Println(banana) // prints &{Banana} }
3. Использование оператора адреса указателя
Оператор адреса указателя (&) можно использовать для объявления структуры. Давайте посмотрим, как мы это сделаем.
package main import ( "fmt" ) type Fruit struct { name string } func main() { var mango = &Fruit{"Mango"} fmt.Println(mango) // prints &{Mango} }
Типы структур в Go
Структура может быть как именованной, так и безымянной или анонимной. Оба имеют свое применение. Мы узнаем, что это такое и как их использовать.
1. Именованная структура
Именованная структура — это любая структура, имя которой было объявлено ранее. Таким образом, его можно инициализировать, используя его имя.
type Food struct {} // Food is the name
2. Анонимная структура
Теперь мы увидим анонимные структуры. Они очень пригодятся. Мы увидим, как мы их создаём и используем.
package main import ( "fmt" ) func main() { pizza := struct { name string }{ name: "Pizza", } fmt.Println(pizza) // prints {Pizza} }
Поля объекта структуры
Структуры имеют поля. Он может быть именным или безымянным. Им могут быть присвоены значения, или они могут оставаться пустыми и, таким образом, иметь нулевое значение. Давайте посмотрим, как их инициализировать и использовать.
1. Именованные поля в структуре
Именованные поля — это поля, имя которых было объявлено в объявлении типа структуры. Ниже приведен пример.
type Food struct { name string // this field has name quantity int // ... }
2. Анонимные поля в структуре
Анонимные поля — это поля, тип которых объявлен только. В примере мы видим, что внутри структуры можно использовать любой тип. Но это может создать неоднозначность и привести к проблеме, как вы увидите в коде.
package main import ( "fmt" ) // none of the fields are named // these are anonymous fields // Throws error because of ambiguity // There are two string fields to choose from // p.string makes no sense to the compiler // type Painting struct { // string // painting's name // string // artist's name // } type Painting struct { string // painting name Artist // artist } type Artist struct { string } func main() { var p Painting p.string = "Starry Night" // p.string = "Van Gogh" // it will throw an error // "ambiguous selector p.string" p.Artist.string = "Van Gogh" fmt.Println(p) // prints {Starry Night {Van Gogh}} }
3. Функции как поле
Структуры могут иметь функции в качестве своего поля. Ниже приведен код, показывающий использование функции внутри структуры.
import ( "fmt" ) // declare function type type FoodNameGetter func(string) string type Food struct { name string getter FoodNameGetter // declare function } func main() { pizza := Food{ name: "Pizza", getter: func(name string) string { // declare function body return "This is " + name + "." }, } fmt.Println(pizza.getter(pizza.name)) // prints "This is Pizza." }
Доступ к полям структуры
Доступ к полям структуры очень прост. Для этого мы используем оператор точки . Когда существует вложенная структура, мы также используем точку внутри вложенной структуры.
// declaration type Car struct { name string cost int } var c Car = Car{"Mercedes", 3500000} // accessing carMake := c.name carPrice := c.cost
Теперь для вложенной структуры мы можем сделать следующее:
package main import ( "fmt" ) type User struct { name string } type Service struct { name string user User } func main() { google := Service{ name: "Google", user: User{ name: "John Doe", }, } // accessing from nested struct fmt.Println(google.user.name) // prints "John Doe" }
Продвигаемые поля
Когда мы используем анонимную структуру внутри другой структуры, все поля анонимной структуры становятся доступными из внешней структуры, как если бы они были ее частью. Эти поля называются продвигаемыми полями.
package main import ( "fmt" ) type Person struct { name string } type StoreKeeper struct { Person } func main() { var p = StoreKeeper{} p.Person = Person{"Jane Doe"} // access the field as normal field fmt.Println(p.name) // prints "Jane Doe" }
Использование указателей структуры
Мы можем создавать указатели на структуру, используя оператор адреса (&) . Вот пример, показывающий именно это.
package main import ( "fmt" ) type Student struct { name string } func main() { ptrStudent := &Student{name: "John"} fmt.Println(ptrStudent) // prints &{John} }
Мы можем использовать функцию new() , чтобы получить указатель на эту структуру.
Сравнение структур
Структуры можно сравнивать, если они имеют одинаковые значения в одних и тех же полях. Вот пример.
package main import ( "fmt" ) type Student struct { name string } func main() { s1 := Student{"John"} s2 := Student{"John"} if(s1 == s2) { fmt.Println("They are equal") } else { fmt.Println("They are not equal") } // output: "They are equal" }
Массив структур
Теперь мы увидим, как использовать структуры в массивах. Это довольно просто и понятно.
1. Объявление и инициализация массива структур
Мы просто объявляем массив с типом этой структуры.
var arrayOfStruct []StructName // declaration
2. Вставка значений в массив структур
Используйте функцию добавления, которая возвращает фрагмент после вставки.
package main import ( "fmt" ) type Student struct { name string } func main() { // declare array var students []Student s := Student{"Kate"} kate := append(students, s) fmt.Println(kate) // [{Kate}] }
Или мы можем просто использовать такую индексацию.
students[1] = Student{"Peter"}
Вот как мы можем использовать структуры в Go для различных целей.