go语言结构体学习笔记

结构体

结构体是由相同或者不同类型的数据构成的集合。

成员变量也可以称之为“字段”

和面向对象语言中的类似乎是差不多。但是go语言没有明确的面向对象的概念。

结构体的定义和初始化

type People struct {
    Name  string
    Age string
    Address  string
}

以上,这样就声明了一个struct(结构体)

初始化结构体

  1. 按默认顺序初始化

    p1 := People{"Zhang San", 22, "China"}	
    
  2. 按字段的赋值初始化

    p2 := People{Name: "Zhang San", Age: 22, Address: "China"}
    
  3. new的方式

    p3 := new(People)
    p3.age = 22
    

make和new操作

make用于内建模型map、slice、channel的内存分配。

new用于各种类型的内存分配。

内建函数new本质上说跟其他语言的同名函数功能是一样的,new(T)分配了零值填充的T类型的内存空间,

并且返回地址,即*T类型的值,返回了一个指针,指向新分配的类型T的零值。

new 返回的是指针。

内建函数make 与new有着不同的功能,make只能创建slice、map和channel,并且返回一个有初始值的T类型,而不是指针。

本质上来讲,导致三个类型有所不同的原因是指向数据结构的引用在使用前必须被初始化。

结构体权限控制

其中没有像Java语言中public、protected、private等关键字的声明。

golang用另外一种做法来实现属性的访问权限:属性的首字母是大写的,在其它包中可以被访问。

否则只能在本包中访问。类的声明和方法也是一样的。

结构体的内存布局

Go 语言中,结构体和它所包含的数据在内存中是以连续块的形式存在的,即使结构体中嵌套有其他的结构体,这在性能上带来了很大的优势。不像 Java 中的引用类型,一个对象和它里面包含的对象可能会在不同的内存空间中,这点和 Go 语言中的指针很像。下面的例子清晰地说明了这些情况:

函数传递结构体

函数中结构体加和没有加*的区别在于一个是传递指针对象,一个是传递值对象。

加&符号和new的是指针对象,没有的则是值对象,这点和php、java不一致,在传递对象的时候要根据实际情况来决定是要传递指针还是值。

当对象比较小的时候传递指针并不划算

func main() {

	p := People{"zhang san", 99, "China"}
	func1(p)
	fmt.Println("func1 执行后,age : ", p.Age)
	func2(&p)
	fmt.Println("func2 执行后,age : ", p.Age)
}

type People struct {
	Name    string
	Age     int
	Address string
}

func func1(people People) {
	fmt.Println("传递指针的函数执行前 age:", people.Age)
	people.Age = 0
	fmt.Println("传递指针的函数执行完毕")
}

func func2(people *People) {
	fmt.Println("传递指针的函数执行前 age:", people.Age)
	people.Age = 1 //此时传递的是指针,修改指针指向的数据
	fmt.Println("传递指针的函数执行完毕")

}

传递指针的函数执行前 age: 99
传递指针的函数执行完毕
func1 执行后,age :  99
传递指针的函数执行前 age: 99
传递指针的函数执行完毕
func2 执行后,age :  1

匿名结构体

p := struct {
    Name string
    Gender string
    Age uint8
}{"Robert", "Male", 33}

匿名结构体最大的用处是在内部临时创建一个结构以封装数据,而不必正式为其声明相关规则。

匿名字段

匿名字段,默认使用数据类型作为名字,所以匿名字段类型不能重复,否则会发生冲突

type People struct {
	Name    string
	Age     int
	Address string
	string //匿名字段,默认使用数据类型作为名字,所以匿名字段类型不能重复,否则会发生冲突
}
func main() {
	p := People{"zhang san", 99, "China", "beijing"}
	fmt.Println(p) //{zhang san 99 China beijing}
}

type People struct {
	Name    string
	Age     int
	Address string
	string
}

结构体嵌套结构体

下面我们举个例子:比如说People里面还有个School

func main() {
	p := People{Name: "zhang san", Age: 99, Address: "China"}
	p.School = School{"Beijing Univ", 3}
	fmt.Println(p) //{zhang san 99 China {Beijing Univ 3}}
}

type People struct {
	Name    string
	Age     int
	Address string
	School  School
}

type School struct {
	schoolName string
	classNo    int
}

go语言中,因为结构体是值传递,所以如果我们仅仅是赋值的话,在结构体嵌套结构体的情况下,可以用结构体指针来代替值传递。这样的好处是什么,当然是省内存啦!

func main() {
	p := People{Name: "zhang san", Age: 99, Address: "China"}
	s := &School{"Qinghua", 8}
	p.School = s
	fmt.Println(p) //{zhang san 99 China 0xc00009a040}
}

type People struct {
	Name    string
	Age     int
	Address string
	School  *School
}

type School struct {
	schoolName string
	classNo    int
}

posted on 2020-03-05 22:03  长方形  阅读(222)  评论(0编辑  收藏  举报

导航