Go语言学习之旅--结构体
Posted 赵jc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言学习之旅--结构体相关的知识,希望对你有一定的参考价值。
结构体
在定义结构体之前,我们先来看看什么是类型定义和类型别名
go语言类型定义
类型定义的语法
type NewType Type
举例
func main()
//类型定义
type MyInt int
//i为MyInt类型
var i MyInt
i = 100
fmt.Printf("i: %v i: %T\\n", i, i)
go语言类型别名
类型别名语法
type NewType = Type
举例
func main()
//类型别名定义
type MyInt2 = int
//i还是int类型
var i MyInt2
i = 100
fmt.Printf("i: %v i: %T\\n", i, i)
go语言类型定义和类型别名的区别
- 1.类型定义相当于定义了一个全新的类型,与之前的类型不同;但是类型别名并没有定义一个新的类型,而是使用一个别名来替换之前的类型
- 2.类型别名只会在代码中存在,在编译完成之后并不会存在该别名
- 3.因为类型别名和原来的类型是一致的,所以原来类型所拥有的方法,类型别名中也可以调用,但是如果是重新定义的一个类型,那么不可以调用之前的任何方法
结构体
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
结构体成员,在没有赋值之前都是零值。
结构体的初始化
- 未初始化的结构体
成员都是默认值 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)
- 使用键值对对结构体进行初始化
package main
import "fmt"
func main()
type Person struct
id, age int
name, email string
kite := Person
id: 1,
name: "kite",
age: 20,
email: "zjc.com",
fmt.Printf("kite: %v\\n", kite)
- 使用值的列表初始化
注意:
- 必须初始化结构体的所有字段。
- 初始值的填充顺序必须与字段在结构体中的声明顺序一致。
- 该方式不能和键值初始化方式混用。
package main
import "fmt"
func main()
type Person struct
id, age int
name, email string
kite := Person
1,
20,
"kite",
"zjc.com",
fmt.Printf("kite: %v\\n", kite)
- 部分成员初始化
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)
访问结构体成员
可以使用点运算符(.),来访问结构体成员,例如:
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 = "zjc.com"
fmt.Printf("tom: %v\\n", tom)
匿名结构体
如果结构体是临时使用,可以不用起名字,直接使用,例如:
package main
import "fmt"
func main()
var dog struct
id int
name string
dog.id = 1
dog.name = "旺财"
fmt.Printf("dog: %v\\n", dog)
结构体指针
举例
package main
import "fmt"
func main()
type Person struct
id int
name string
var tom = Person1, "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)
使用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)
访问结构体指针成员
访问结构体指针成员,也使用点运算符(.),例如:
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)
结构体作为函数参数
定义
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 := Person1, "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 := Person1, "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
从运行结果,我们可以看到,调用函数后,参数被改变了。
嵌套结构体
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
Animalname: "cat",
age: 3,
dog.eat()
dog.sleep()
cat.eat()
cat.sleep()
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 &Personname: name, age: age, nil
func main()
person, err := NewPerson("tom", 20)
if err == nil
fmt.Printf("person: %v\\n", *person)
本篇文章借鉴https://blog.csdn.net/geek99_guo/article/details/121752993?spm=1001.2014.3001.5502写的,如有不对可以评论留言
以上是关于Go语言学习之旅--结构体的主要内容,如果未能解决你的问题,请参考以下文章