Go语言提供了和C语言概念一致的结构体。数组存的元素都是同一种数据类型,而结构体中可以存储不同类型的数据。结构体和指针是为什么称Go语言是类C语言的重要原因,因为两者在这两个概念上是完全一致的。
结构体是由一系列相同类型或者不同类型的数据构成的数据集合。
在概念上,结构体表示某一事物的属性集合。比如一首歌可以使用以下属性描述:
结构体使用关键字struct
声明,其定义语法如下:
type struct_variable_type struct {
member1 variable_type1
member2 variable_type2
...
membern variable_typen
}
其中struct_varibale_type
可以自定义,member1
也可以自定义,本质上是一个字符串,可以使用中文或者其他语言,只不过使用英文是潜规则,variable_type
是基本数据类型,完全等同于C语言。
结构体变量以如下语法声明:
varibale_name := structure_varibale_type {value1, value2, ..., valuen}
variable_name := structure_varibale_type {key1: value1, key2: value2, ..., keyn: valuen}
实例:
package main
import "fmt"
type Song struct {
title string // 歌名 string
singer string // 歌手 string
duration float32 // 时长 float32
}
func main() {
song1 := Song{"夕焼けのスターマイン", "今井麻美", 4.35}
fmt.Println(song1)
// 可以创建匿名结构体
fmt.Println(Song{"潮汐", "双笙/泠鸢", 4.53})
fmt.Println(Song{"Angel of the Moring", "Juice Newton", 4.01})
}
// 输出是自带花括号的
// {夕焼けのスターマイン 今井麻美 4.35}
// {潮汐 双笙/泠鸢 4.53}
// {Angel of the Moring Juice Newton 4.01}
结构体可以嵌套定义,比如概念上一张专辑由几首歌组成。实例如下:
package main
import "fmt"
type Song struct {
title string
singer string
duration float32
}
type Album struct {
song1 Song
song2 Song
song3 Song
}
func main() {
song1 := Song{"夕焼けのスターマイン", "今井麻美", 4.35}
song2 := Song{"潮汐", "双笙/泠鸢", 4.53}
song3 := Song{"Angel of the Moring", "Juice Newton", 4.01}
album := Album{song1, song2, song3}
fmt.Println(album)
}
// {{夕焼けのスターマイン 今井麻美 4.35} {潮汐 双笙/泠鸢 4.53} {Angel of the Moring Juice Newton 4.01}}
结构体成员使用.
运算符访问。.
运算符在编程语言中的通用概念即为访问一个集合中的某一个元素。
package main
import "fmt"
type Song struct {
title string
singer string
duration float32
}
type Album struct {
song1 Song
song2 Song
song3 Song
}
func main() {
song1 := Song{"夕焼けのスターマイン", "今井麻美", 4.35}
song2 := Song{"潮汐", "双笙/泠鸢", 4.53}
song3 := Song{"Angel of the Moring", "Juice Newton", 4.01}
album := Album{song1, song2, song3}
fmt.Println(album.song1)
}
// {夕焼けのスターマイン 今井麻美 4.35}
Go语言中也可以定义结构体指针,即指向结构体的指针。语法如下:
var struct_pointer *Song
struct_pointer = &song1
Go语言中结构体也可以作为函数参数传递,结构体指针也可以。那么传结构体和传结构体指针有什么区别呢?
实例(传结构体):
package main
import "fmt"
type Song struct {
title string
singer string
duration float32
}
func cover(song Song, newSinger string) {
song.singer = newSinger
}
func main() {
song := Song{"潮汐", "双笙/泠鸢", 4.53}
cover(song, "Hirro")
fmt.Println(song)
}
// {潮汐 双笙/泠鸢 4.53}
你可以看到歌曲的歌手并没有改成新的翻唱歌手。
实例(传结构体指针):
package main
import "fmt"
type Song struct {
title string
singer string
duration float32
}
func cover(song *Song, newSinger string) {
song.singer = newSinger
}
func main() {
song := Song{"潮汐", "双笙/泠鸢", 4.53}
cover(&song, "Hirro")
fmt.Println(song)
}
// {潮汐 Hirro 4.53}
歌曲的歌手成功改成了新的翻唱歌手。
这就是传结构体和传指针的区别。传结构体是值传递,相当于复制了一份送到函数中,函数修改的只是副本,不是原来的结构体变量;传结构体指针是引用传递,传进去的结构体变量的地址,对改地址指向的内容修改会直接作用到该构体变量。
当然,你可以通过函数返回值覆盖原值来是现更改,但这样做很麻烦,包含了复制、返回值、重新赋值等一系列操作,计算复杂度高了很多。
package main
import "fmt"
type Song struct {
title string
singer string
duration float32
}
func cover(song Song, newSinger string) Song {
song.singer = newSinger
return song
}
func main() {
song := Song{"潮汐", "双笙/泠鸢", 4.53}
song = cover(song, "Hirro")
fmt.Println(song)
}
// {潮汐 Hirro 4.53}
这个例子体现了指针的灵活性。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有