Structs
Go’s structs are typed collections of fields. They’re useful for grouping data together to form records.
type Entry struct {
Key string
Value int
}
var entry Entry // empty struct
struct являются значениями
При присваивании
:=
struct полностью копируетсяпеременные типа struct не могут иметь ссылку на
nil
The number of fields of a struct type can be zero.
var entry Entry
- создаст структуру со значениями равными значению по умолчанию для своего типа, то естьvar entry Entry = Entry {Key: "", Value: 0}
.A struct type can't have a field of the struct type itself, neither directly nor recursively.
Сравнение:
struct
сравниваются по значению. Две структуры считаются равными если они имеют одинаковые поля.Whether or not a struct is comparable depends on the struct’s fields. Structs that are entirely composed of comparable types are comparable; those with slice or map fields are not (function and channel fields also prevent a struct from being comparable).
If two struct variables are being compared and at least one of them has a type that’s an anonymous struct, you can compare them without a type conversion if the fields of both structs have the same names, order, and types.
Доступ
Struct fields are accessed using a dot.
Structs are mutable.
You can also use dots with struct pointers - the pointers are automatically dereferenced.
You can list just a subset of fields by using the Name: syntax. (And the order of named fields is irrelevant.)
Структура типа
S
не может содержать поле такого же типаS
(агрегатное значение не может содержать само себя), но может объявить поле с типом указателя на*S
.
var config struct {
APIKey string
OAuthConfig oauth.Config
}
config.APIKey = "BADC0C0A"
Test tables:
var indexRuneTests = []struct {
s string
rune rune
out int
}{
{"a A x", 'A', 2},
{"some_text=some_value", '=', 9},
{"☺a", 'a', 3},
{"a☻☺b", '☺', 4},
}
When a struct value is assigned to another struct value, the effect is the same as assigning each field one by one.
func f() {
book1 := Book{pages: 300}
book2 := Book{"Go 101", "Tapir", 256}
book2 = book1
// The above line is equivalent to the
// following lines.
book2.title = book1.title
book2.author = book1.author
book2.pages = book1.pages
}
Embedded structures
Struct types have the ability to contain anonymous or embedded fields. This is also called embedding a type. When we embed a type into a struct, the name of the type acts as the field name for what is then an embedded field.
type User struct {
Name string
Email string
}
type Admin struct {
User
Level string
}
func main() {
admin := Admin{
User: User{
Name: "john smith",
Email: "john@email.com",
},
Level: "super",
}
fmt.Println(admin.Name) // john smith
}
We have declared a new type called Admin
and embedded the User
type within the struct declaration. This is not inheritance but composition. There is no relationship between the User
and the Admin
type.
The type that is embedded is then called an inner
type of the new outer
type. Through inner type promotion, identifiers from the inner
type are promoted up to the outer
type. These promoted identifiers become part of the outer
type as if they were declared explicitly by the type itself. The outer
type is then composed of every- thing the inner type contains, and new fields and methods can be added. We still can access the inner
type's method directly.
admin.User.Name
type Person struct {
Name string
Age int
}
type Singer struct {
Person // extends Person by embedding it
works []string
}
var gaga = Singer{Person: Person{"Gaga", 30}}
Please note that, a Singer
value is not a Person
value, the following code doesn't compile:
var gaga = Singer{}
var _ Person = gaga
Embedding an interface in a struct automatically defines all of the interface’s methods on the struct. It doesn’t provide any implementations of those methods, so you need to implement the methods that you care about.
Methods for embedded types
Для встроенных структур работает следующее правило: метод, определенный на User
будет так же применим Admin
, поскольку User
встроен в Admin
(обратное неверно):
func (u *User) Notify() {
log.Printf("User: Sending User Email To %s<%s>\n",
u.Name,
u.Email)
}
func main() {
admin := &Admin{
User: User{
Name: "john smith",
Email: "john@email.com",
},
Level: "super",
}
admin.Notify() // User: Sending User Email To john smith<john@email.com>
}
Function overloading for embedded structures
Переопределение функций работает в Go для разных типов структур:
func (u User) GetName() string {
return u.Name
}
func (u Admin) GetName() string {
return "ADMIN"
}
Functional Fields
Полями структур могут быть методы
Anonymous Struct Types
Anonymous struct types are allowed to be used as the types of the fields of another struct type. Anonymous struct type literals are also allowed to be used in composite literals.
var aBook = struct {
// The type of the author field is
// an anonymous struct type.
author struct {
firstName, lastName string
gender bool
}
title string
pages int
}{
author: struct { // an anonymous struct type
firstName, lastName string
gender bool
}{
firstName: "Mark",
lastName: "Twain",
},
title: "The Million Pound Note",
pages: 96,
}
Struct tags
Last updated
Was this helpful?