go语言---结构体及结构体指针

结构体(struct),是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。 (可以理解为其他编程语言中的类)

  1. 结构体既可以定义在函数内,也可以定义在函数外,函数外为全局结构体可以跨包访问(前提是结构体首字母大写)
  2. 结构体变量是值类型,可以使用fmt.Printf("%p", &结构体变量)来查看其内存地址;由于结构体是值类型,在方法传递时,希望传递的是结构体地址,这时就可以使用结构体指针来完成,可以结合new(T)函数创建结构体指针;
  3. 双等于号比较时候,看两侧是什么类型,如果是值类型,就看内容是否相同,即使地址不同,也为true,如果两侧是指针类型,就会比较内存地址是否相同;
package main

import (
	"fmt"
)

// 声明结构体,可以理解为创建一个类
type People struct { // 结构体名称首字母大写,能被其他包访问,小写无法被其他包访问(包括其属性也无法被访问);
	Name string // 属性1  如果结构体能被访问,这里的大写就能被其他包访问,小写无法被其他包访问;可以理解为有2道门;
	age  int    // 属性2
}

func main() {
	// 声明结构体变量
	// 只声明不赋值
	var p1 People
	fmt.Println(p1) // { 0}  初始值为对应类型的默认值; string类型默认值为空字符串;int类型默认为0;

	// 声明的同时赋值, 位置参数
	p2 := People{"张三", 24}
	fmt.Println(p2) // {张三 24}

	// 声明的同时赋值, 关键字参数
	p3 := People{age: 22, Name: "李四"}
	fmt.Println(p3) // {李四 22}

	// 获取结构体变量对应的值:
	fmt.Println(p1.Name, p1.age) //  0
	fmt.Println(p2.Name, p2.age) // 张三 24
	fmt.Println(p3.Name, p3.age) // 李四 22

	//在结构体中,用"=="判断的是结构体中的内容是否相同,如果地址不同,但是内容相同,返回值就为true
	// 再声明一个结构体变量p4, 明显这个结构体变量与p2不同,如果给p4赋值和p2一样
	var p4 People
	p4.age = 24
	p4.Name = "张三"

	// 利用双等于号"=="来判断
	fmt.Printf("p2: %p, p4: %p \n", &p2, &p4) // p2: 0xc0000044e0, p4: 0xc000004540
	fmt.Println("p2==p4? ", p2 == p4)         // p2==p4?  true

	// 结构体指针
	p5 := new(People)  // 结构体是值类型,所以创建结构体指针时已经开辟了内存空间
	fmt.Println(p5)  // &{ 0}
	fmt.Println(p5 == nil)  // false

	// 由于结构体中的值不是指针类型,所以可以直接调用
	p5.Name = "王五"
	fmt.Println(p5)  // &{王五 0}

	// 由于p5是使用new()函数创建出来的,所以p5是指针
	p6 := p5
	fmt.Println(p5, p6)  // &{王五 0} &{王五 0}
	fmt.Printf("p5: %p,  p6: %p \n", p5, p6)  // p5: 0xc000096500,  p6: 0xc000096500   引用类型不用&取地址

	// 从上面的地址可以看到,p5和p6指向的是同一个内存地址,所以,修改其中一个,就会影响另外一个
	p5.age = 23
	p6.Name = "赵六"
	fmt.Println(p5, p6)  // &{赵六 23} &{赵六 23}

	// 双等于号比较时候,看两侧是什么类型,如果是值类型,就看内容是否相同,即使地址不同,也为true,如果两侧是指针类型,就会比较内存地址是否相同;
	p7 := &People{"A", 23}
	p8 := &People{"A", 23}
	fmt.Printf("p7: %T, p8: %T \n", p7, p8)  // p7: *main.People, p8: *main.People
	fmt.Printf("p7: %p, p8: %p \n", p7, p8)  // p7: 0xc000004640, p8: 0xc000004660
	fmt.Println("p7 == p8 ?", p7 == p8)  // p7 == p8 ? false

	// 值类型与指针类型比较时的转换: *指针类型, &值类型
	p9 := People{"A", 23}
	fmt.Println("p8==&p9?", p8==&p9)  // p8==p9? false  使用&p9取到p9的地址,这时候两边都是指针类型,需要判断内存地址是否相同
	fmt.Println("*p8==p9?", *p8==p9)  // p8==p9? true  使用*p8取到指针p8里面的值,这时候两边都是值类型,只需判断内容是否相同
}

发布了22 篇原创文章 · 获赞 1 · 访问量 1827

猜你喜欢

转载自blog.csdn.net/weixin_42677653/article/details/105176178