golang 结构体总结
2021/12/7 13:16:46
本文主要是介绍golang 结构体总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
golang 结构体
go语言没有面向对象的概念了,但是可以使用结构体来实现,面向对象编程的一些特性,例如:继承、组合等特性。
go语言结构体的定义
上一节我们介绍了类型定义,结构体的定义和类型定义类似,只不过多了一个struct
关键字,语法结构如下:
type struct_variable_type struct { member definition; member definition; ... member definition; }
type
:结构体定义关键字
struct_variable_type
:结构体类型名称
struct
:结构体定义关键字
member definition;
:成员定义
实例
下面我们定义一个人的结构体Person
type Person struct { id int name string age int email string }
以上我们定义一个Person结构体,有四个成员,来描述一个Person的信息。
形同类型的可以合并到一行,例如:
type Person struct { id, age int name, email string }
声明一个结构体变量
声明一个结构体变量和声明一个普通变量相同,例如:
var tom Person fmt.Printf("tom: %v\n", tom) kite := Person{} fmt.Printf("kite: %v\n", kite)
也行结果
tom: {0 0 } kite: {0 0 }
结构体成员,在没有赋值之前都是零值。
访问结构体成员
可以使用点运算符(.
),来访问结构体成员,例如:
package main import "fmt" func main() { type Person struct { id, age int name, email string } var tom Person tom.id = 1 tom.name = "tom" tom.age = 20 tom.email = "tom@gmail.com" fmt.Printf("tom: %v\n", tom) }
运行结果如下
tom: {1 20 tom tom@gmail.com}
匿名结构体
如果结构体是临时使用,可以不用起名字,直接使用,例如:
package main import "fmt" func main() { var dog struct { id int name string } dog.id = 1 dog.name = "花花" fmt.Printf("dog: %v\n", dog) }
golang结构体的初始化
未初始化的结构体,成员都是零值 int 0 float 0.0 bool false string nil nil
实例
package main import "fmt" func main() { type Person struct { id, age int name, email string } var tom Person fmt.Printf("tom: %v\n", tom) }
运行结果
tom: {0 0 "" ""}
使用键值对对结构体进行初始化
实例
package main import "fmt" func main() { type Person struct { id, age int name, email string } kite := Person{ id: 1, name: "kite", age: 20, email: "kite@gmail.com", } fmt.Printf("kite: %v\n", kite) }
运行结果
kite: {1 20 kite kite@gmail.com}
使用值的列表初始化
实例
package main import "fmt" func main() { type Person struct { id, age int name, email string } kite := Person{ 1, 20, "kite", "kite@gmail.com", } fmt.Printf("kite: %v\n", kite) }
运行结果
kite: {1 20 kite kite@gmail.com}
注意:
- 必须初始化结构体的所有字段。
- 初始值的填充顺序必须与字段在结构体中的声明顺序一致。
- 该方式不能和键值初始化方式混用。
部分成员初始化
用不到的成员,可以不进行初始化
package main import "fmt" func main() { type Person struct { id, age int name, email string } kite := Person{ id: 1, name: "kite", } fmt.Printf("kite: %v\n", kite) }
运行结果
kite: {1 0 kite "" }
golang结构体指针
结构体指针和普通的变量指针相同,我先来回顾一下普通变量的指针,例如:
package main import "fmt" func main() { var name string name = "tom" // p_name 指针类型 var p_name *string // &name 取name地址 p_name = &name fmt.Printf("name: %v\n", name) // 输出指针地址 fmt.Printf("p_name: %v\n", p_name) // 输出指针指向的内容值 fmt.Printf("*p_name: %v\n", *p_name) }
运行结果
name: tom p_name: 0xc00010e120 *p_name: tom
go结构体指针
实例
package main import "fmt" func main() { type Person struct { id int name string } var tom = Person{1, "tom"} var p_person *Person p_person = &tom fmt.Printf("tom: %v\n", tom) fmt.Printf("p_person: %p\n", p_person) fmt.Printf("*p_person: %v\n", *p_person) }
运行结果
tom: {1 tom} p_person: 0xc000004078 *p_person: {1 tom}
使用new
关键字创建结构体指针
我们还可以通过使用new
关键字对结构体进行实例化,得到的是结构体的地址,例如:
package main import "fmt" func main() { type Person struct { id int name string } var p_person = new(Person) fmt.Printf("p_person: %T\n", p_person) }
运行结果
p_person: *main.Person
从运行结果,我们发现p_person为指针类型
访问结构体指针成员
访问结构体指针成员,也使用点运算符(.
),例如:
package main import "fmt" func main() { type Person struct { id int name string } var p_person = new(Person) fmt.Printf("p_person: %T\n", p_person) p_person.id = 1 p_person.name = "tom" fmt.Printf("*p_person: %v\n", *p_person) }
运行结果
p_person: *main.Person *p_person: {1 tom}
golang结构体作为函数参数
go结构体可以像普通变量一样,作为函数的参数,传递给函数,这里分为两种情况:
- 直接传递结构体,这是是一个副本(拷贝),在函数内部不会改变外面结构体内容。
- 传递结构体指针,这时在函数内部,能够改变外部结构体内容。
直接传递结构体
实例
package main import "fmt" type Person struct { id int name string } func showPerson(person Person) { person.id = 1 person.name = "kite" fmt.Printf("person: %v\n", person) } func main() { person := Person{1, "tom"} fmt.Printf("person: %v\n", person) fmt.Println("----------------") showPerson(person) fmt.Println("----------------") fmt.Printf("person: %v\n", person) }
运行结果
person: {1 tom} ---------------- person: {1 kite} ---------------- person: {1 tom}
从运行结果可以看出,函数内部改变了结构体内容,函数外面并没有被改变。
传递结构体指针
实例
package main import "fmt" type Person struct { id int name string } func showPerson(person *Person) { person.id = 1 person.name = "kite" fmt.Printf("person: %v\n", person) } func main() { person := Person{1, "tom"} fmt.Printf("person: %v\n", person) fmt.Println("----------------") showPerson(&person) fmt.Println("----------------") fmt.Printf("person: %v\n", person) }
运行结果
person: {1 tom} ---------------- person: &{1 kite} ---------------- person: {1 kite}
从运行结果,我们可以看到,调用函数后,参数被改变了。
golang嵌套结构体
go语言没有面向对象编程思想,也没有继承关系,但是可以通过结构体嵌套来实现这种效果。
下面通过实例演示如何实现结构体嵌套,加入有一个人Person
结构体,这个人还养了一个宠物Dog
结构体。
下面我们来看一下:
Dog结构体
type Dog struct { name string color string age int }
Person结构体
type person struct { dog Dog name string age int }
访问它们
package main import "fmt" type Dog struct { name string color string age int } type person struct { dog Dog name string age int } func main() { var tom person tom.dog.name = "花花" tom.dog.color = "黑白花" tom.dog.age = 2 tom.name = "tom" tom.age = 20 fmt.Printf("tom: %v\n", tom) }
运行结果
tom: {{花花 黑白花 2} tom 20}
golang继承
golang本质上没有oop的概念,也没有继承的概念,但是可以通过结构体嵌套实现这个特性。
例如
package main import "fmt" type Animal struct { name string age int } func (a Animal) eat() { fmt.Println("eat...") } func (a Animal) sleep() { fmt.Println("sleep") } type Dog struct { Animal } type Cat struct { Animal } func main() { dog := Dog{ Animal{ name: "dog", age: 2, }, } cat := Cat{ Animal{name: "cat", age: 3}, } dog.eat() dog.sleep() cat.eat() cat.sleep() }
golang模拟OOP的属性和方法
golang没有面向对象的概念,也没有封装的概念,但是可以通过结构体struct
和函数绑定来实现OOP的属性和方法等特性。接收者 receiver 方法。
例如,想要定义一个Person类,有name和age属性,有eat/sleep/work方法。
package main import "fmt" type Person struct { name string age int } func (per Person) eat() { fmt.Println("eat...") } func (per Person) sleep() { fmt.Println("sleep...") } func (per Person) work() { fmt.Println("work...") } func main() { per := Person{ name: "tom", age: 20, } fmt.Printf("per: %v\n", per) per.eat() per.sleep() per.work() }
golang构造函数
golang没有构造函数的概念,可以使用函数来模拟构造函数的的功能。
例如
package main import "fmt" type Person struct { name string age int } func NewPerson(name string, age int) (*Person, error) { if name == "" { return nil, fmt.Errorf("name 不能为空") } if age < 0 { return nil, fmt.Errorf("age 不能小于0") } return &Person{name: name, age: age}, nil } func main() { person, err := NewPerson("tom", 20) if err == nil { fmt.Printf("person: %v\n", *person) } }
这篇关于golang 结构体总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-15SendGrid 的 Go 客户端库怎么实现同时向多个邮箱发送邮件?-icode9专业技术文章分享
- 2024-11-15SendGrid 的 Go 客户端库怎么设置header 和 标签tag 呢?-icode9专业技术文章分享
- 2024-11-12Cargo deny安装指路
- 2024-11-02MongoDB项目实战:从入门到初级应用
- 2024-11-01随时随地一键转录,Google Cloud 新模型 Chirp 2 让语音识别更上一层楼
- 2024-10-25Google Cloud动手实验详解:如何在Cloud Run上开发无服务器应用
- 2024-10-24AI ?先驱齐聚 BAAI 2024,发布大规模语言、多模态、具身、生物计算以及 FlagOpen 2.0 等 AI 模型创新成果。
- 2024-10-20goland工具下,如修改一个项目的标准库SDK的版本-icode9专业技术文章分享
- 2024-10-17Go学习:初学者的简单教程
- 2024-10-17Go学习:新手入门完全指南