Go语言结构体与初始化图文详解
Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型。
结构体是复合类型,当需要定义类型,它由一系列属性组成,每个属性都有自己的类型和值的时候,就应该使用结构体,它把数据聚集在一起。
结构体也是值类型,因此可以通过 new 函数来创建
组成结构体类型的那些数据成为字段(fields)。每个字段都有一个类型和一个名字;在一个结构体中,字段名字必须是唯一的。
一,结构体定义
结构体定义的一般方式如下:
type identifier struct { field type1 field type2}
type T struct {a, b int} 也是合法的语法,它更适用于简单的结构体
结构体里的字段都有 名字,像 field1、field2 等,如果字段在代码中从来也不会被用到,那么可以命名它为 _。
结构体类型和字段的命名遵循可见性规则,所以可能存在一个结构体类型的某些字段是导出的,而另一些没有导出。
结构体的字段可以是任何类型,甚至是结构体本身,也可以是函数或者接口。可以声明结构体类型的一个变量,然后像下面这样给它的字段赋值:
var s T s.a = 5 s.b = 8
数组也可以看作是一种结构体类型,不过它使用下标而不是具名的字段
二,初始化
方式一:通过 var 声明结构体
在 Go 语言中当一个变量被声明的时候,系统会自动初始化它的默认值,比如 int 被初始化为 0,指针为 nil。
var 声明同样也会为结构体类型的数据分配内存,所以我们才能像上一段代码中那样,在声明了 var s T 之后就能直接给他的字段进行赋值
方式二:使用 new
使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针:var t *T = new(T)。
type struct1 struct { i1 int f1 float32 str string}func main() { ms := new(struct1) ms.i1 = 10 ms.f1 = 15.5 ms.str= "Chris" fmt.Printf("The int is: %d\n", ms.i1) fmt.Printf("The float is: %f\n", ms.f1) fmt.Printf("The string is: %s\n", ms.str) fmt.Println(ms) }
与面向对象语言相同,使用点操作符可以给字段赋值:structname.fieldname = value。
同样的,使用点操作符可以获取结构体字段的值:structname.fieldname。
方式三:使用字面量
type Person struct { name string age int address string } func main() { var p1 Person p1 = Person{"lisi", 30, "shanghai"} //方式A p2 := Person{address:"beijing", age:25, name:"wangwu"} //方式B p3 := Person{address:"NewYork"} //方式C }
在(方式A)中,值必须以字段在结构体定义时的顺序给出。(方式B)是在值前面加上了字段名和冒号,这种方式下值的顺序不必一致,并且某些字段还可以被忽略掉,就想(方式C)那样。
除了上面这三种方式外,还有一种初始化结构体实体更简短和常用的方式,如下:
ms := &Person{"name", 20, "bj"} ms2 := &Person{name:"zhangsan"}
&Person{a, b, c} 是一种简写,底层仍会调用 new(),这里值的顺序必须按照字段顺序来写,同样它也可以使用在值前面加上字段名和冒号的写法(见上文的方式B,C)。
表达式 new(Type) 和 &Type{} 是等价的。
三,几种初始化方式之间的区别
到目前为止,我们已经了解了三种初始化结构体的方式:
//第一种,在Go语言中,可以直接以 var 的方式声明结构体即可完成实例化 var t T t.a = 1 t.b = 2 //第二种,使用 new() 实例化 t := new(T) //第三种,使用字面量初始化 t := T{a, b} t := &T{} //等效于 new(T)
使用 var t T 会给 t 分配内存,并零值化内存,但是这个时候的 t 的类型是 T
使用 new 关键字时 t := new(T),变量 t 则是一个指向 T 的指针
从内存布局上来看,我们就能看出这三种初始化方式的区别:
使用 var 声明:
使用 new 初始化:
使用结构体字面量初始化:
下面来看一个具体的例子:
package main import "fmt" type Person struct { name string age int } func main() { var p1 Person p1.name = "zhangsan" p1.age = 18 fmt.Printf("This is %s, %d years old\n", p1.name, p1.age) p2 := new(Person) p2.name = "lisi" p2.age = 20 (*p2).age = 23 //这种写法也是合法的 fmt.Printf("This is %s, %d years old\n", p2.name, p2.age) p3 := Person{"wangwu", 25} fmt.Printf("This is %s, %d years old\n", p3.name, p3.age) }
输出:
This is zhangsan, 18 years old This is lisi, 23 years old This is wangwu, 25 years old
上面例子的第二种情况,虽然 p2 是指针类型,但我们仍然可以像 p2.age = 23 这样赋值,不需要像 C++ 中那样使用 -> 操作符,Go 会自动进行转换。
注意也可以先通过 * 操作符来获取指针所指向的内容,再进行赋值:(*p2).age = 23。
结构体的内存布局
Go 语言中,结构体和它所包含的数据在内存中是以连续块的形式存在的,即使结构体中嵌套有其他的结构体,这在性能上带来了很大的优势。不像 Java 中的引用类型,一个对象和它里面包含的对象可能会在不同的内存空间中,这点和 Go 语言中的指针很像。
下面的例子清晰地说明了这些情况:
type Rect1 struct {Min, Max Point } type Rect2 struct {Min, Max *Point }
更多go语言知识请关注PHP中文网go语言教程栏目。
Atas ialah kandungan terperinci Go语言结构体与初始化图文详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Masalah Threading Giliran di GO Crawler Colly meneroka masalah menggunakan Perpustakaan Colly Crawler dalam bahasa Go, pemaju sering menghadapi masalah dengan benang dan permintaan beratur. � ...

Perpustakaan yang digunakan untuk operasi nombor terapung dalam bahasa Go memperkenalkan cara memastikan ketepatannya ...

Perpustakaan mana yang dibangunkan oleh syarikat besar atau projek sumber terbuka yang terkenal? Semasa pengaturcaraan di GO, pemaju sering menghadapi beberapa keperluan biasa, ...

Perbezaan antara percetakan rentetan dalam bahasa Go: perbezaan kesan menggunakan fungsi println dan rentetan () sedang ...

GO LANGUAGE SLISE INDEX: Mengapa kepingan tunggal elemen memintas dari Indeks 1 tanpa ralat? Dalam bahasa Go, kepingan adalah struktur data yang fleksibel yang boleh merujuk kepada bahagian bawah ...

GO Pointer Syntax dan menangani masalah dalam penggunaan perpustakaan Viper semasa pengaturcaraan dalam bahasa Go, adalah penting untuk memahami sintaks dan penggunaan petunjuk, terutama dalam ...

Mengenai masalah tag struktur tersuai di Goland apabila menggunakan Goland untuk pembangunan bahasa Go, anda sering menghadapi beberapa masalah konfigurasi. Salah satu daripada mereka adalah ...

Strategi Pengoptimuman Prestasi untuk GO Language URL Access Massive Artikel ini mencadangkan penyelesaian pengoptimuman prestasi untuk masalah menggunakan bahasa Go untuk memproses akses URL secara besar -besaran. Program sedia ada dari CSV ...
