Go结构体

结构体

一系列属性的集合

Go 不支持类,而是提供了[结构体]。结构体中可以添加[方法]。这样可以将数据和操作数据的方法绑定在一起,实现与类相似的效果。

所以可以近似的认为结构体就是python中的类

使用结构体,而非类

定义结构体

//Project2/entipy

package entity


//注意名字大小写,大写可以被外部导入引用

type Person struct {
   //结构体中命名也是一样的
   Name string
   age int
   sex string
}

image-20210223082355742

image-20210223082729456

image-20210223082905402

结构体的使用

基本使用(定义并初始化)

package main

import (
	//import "Project2/entity"
	Pe "Project2/entity"
	"fmt"
)

func main() {
	//结构体的使用,值类型,他的零值是他属性的零值
	var p Pe.Person
	p.Name="李逵"  //这里是赋值操作
	p.Age=21
	p.Sex="男"
	fmt.Println(p)
	fmt.Println(p.Name)
}

image-20210223083257269

定义并初赋初值

func main() {

   var p2 =Pe.Person{Name: "宋江",Age: 24,Sex: "男"}
   var p3 =Pe.Person{Name: "李广"}  //不按位置少传,忽略的字段会被设置零值
   var p4 =Pe.Person{"武松",21,"男"} //按位置必须全传
   fmt.Println(p2)
   fmt.Println(p3)
   fmt.Println(p4)
}

image-20210223084540472

创建匿名结构体

匿名结构体的使用
  • 当定义多个变量(类型不限),想一次使用,就可以定义到结构体中
func main() {
//匿名结构体(定义在外面(函数,或者机构体内部))只用一次
	H := struct {  //只能使用类型推导
		HobbyId int
		HobbyName string
	}{1,"足球"}  //定义并初始化
	fmt.Println(H)
	print(H.HobbyName)  //最开始就是使用print后面开始使用fmt,最好不要用
}

image-20210223115335639

结构体零值

就是属性的零值,所以结构体是值类型,也就是会复制一份,在函数中修改不会影响其他的

func test2(person entity.Person)  {
   person.Age=21
   fmt.Println(person)
}

func main() {
	var per entity.Person  //声明了一个结构体
	fmt.Println(per)  //打印结构体
	test2(per)  //执行test2函数,里面修改了age
	fmt.Println(per)  //打印结构体
}

image-20210223120109517

访问结构体的字段

点号操作符 . 用于访问结构体的字段。

还可以创建零值的 struct,以后再给各个字段赋值。

package main

import (
    "fmt"
)

type Employee struct {  
    firstName, lastName string
    age, salary         int
}

func main() {  
    var emp7 Employee
    emp7.firstName = "Jack"
    emp7.lastName = "Adams"
    fmt.Println("Employee 7:", emp7)
}

结构体的指针

指向结构体的指针,使用起来跟真实的结构体是一样的

package main

import (
   "Project2/entity"
   "fmt"
)

func main() {
   var per *entity.Person  //指针的零值
   fmt.Println(per)
}

//指针的零值就是<nill>
------------------------------------------------------
<nill>
package main

import (
   "Project2/entity"
   "fmt"
)

func main() {
   var per=&entity.Person{}
   fmt.Println(per)
   // 把per的名字修改
   (*per).Name="郭麒麟"
   fmt.Println(per)
   // 支持直接使用(数组也是这样,自动帮你处理)
   per.Name = "锅贴"
   fmt.Println(per)
}

---------------------------------------------------
&{ 0 }
&{郭麒麟 0 }
&{锅贴 0 }

匿名字段(字段没有名字,只有类型)

匿名字段类型就是字段名,所以类型不能重复

package main

import "fmt"

//定义匿名结构体
type Per struct {
	string
	int
	sex string //存在两个相同类型匿名的话,会导致解析错误
}

func main() {
	per := Per{"李逵", 13, "男"} //不按位置传正常就行
	fmt.Println(per.string)
	per2 := Per{string: "宋江", int: 14, sex: "男"}  //位置传参是函数类型作为位置名字
	fmt.Println(per2.int)
	per3 :=Per{string:"李广"}
	fmt.Println(per3.sex)
}

image-20210223122317842

匿名字段的使用–变量提升

嵌套结构体(结构体中嵌套结构体)

子类继承父类(结构体的嵌套,匿名嵌套),子类可以继承父类的属性和方法

嵌套结构体的定义

import "fmt"

func main() {
	type Hobby struct {
		int
		string
	}
	type Name struct {
		id int
		name string
		sex string
		Hobby Hobby  //最好是先定义再引用
	}
	// 按位置传参,实例化结构体的时候要把名字带进去,不然不知道是哪个结构体
	name := Name{id: 1,name: "花荣",sex: "男",Hobby: Hobby{1,"足球"}}
	name2 := Name{id: 1,name: "嘿哈",sex: "男",Hobby: Hobby{int:1,string:"足球"}}
	fmt.Println(name)
	fmt.Println(name2)

}
---------------------------------------------------------------------
{1 花荣 男 {1 足球}}
{1 嘿哈 男 {1 足球}}

嵌套结构体的使用

name := Name{id: 1,name: "花荣",sex: "男",Hobby: Hobby{1,"足球"}}
name2 := Name{id: 1,name: "嘿哈",sex: "男",Hobby: Hobby{int:1,string:"足球"}}
name.Hobby.string = "篮球"
fmt.Println(name.Hobby.string)
fmt.Println(name2.name)
---------------------------------------------------------------------
篮球
嘿哈

字段提升

就像面向对象的继承,子类继承父类(结构体的嵌套,匿名嵌套),子类可以继承父类的属性和方法

import "fmt"

func main() {
   type Hobby struct {
      id int
      hbnane string
   }
   type Name struct {
      id int
      name string
      sex string
      Hobby  //现在定义为匿名自担
   }
   // 按位置传参,实例化结构体的时候要把名字带进去,不然不知道是哪个结构体
   name := Name{id: 1,name: "花荣",sex: "男",Hobby: Hobby{1,"足球"}}
   name2 := Name{id: 1,name: "嘿哈",sex: "男",Hobby: Hobby{id:1,hbnane:"足球"}}
   name.hbnane = "篮球" //可以直接提升到上一级,就python中的继承
   fmt.Println(name.Hobby.hbnane)  //类似python中的super,指名道姓的寻找,或者直接找
	fmt.Println(name.Hobby.hbnane)
	fmt.Println(name2.id)  //优先使用自己的

}

导出结构体字段

如果结构体名称以大写字母开头,则它是其他包可以访问的导出类型(Exported Type)。同样,如果结构体里的字段首字母大写,它也能被其他包访问到。

结构体相等性

结构体是值类型。如果它的每一个字段都是可比较的,则该结构体也是可比较的。如果两个结构体变量的对应字段相等,则这两个变量也是相等的。

package main

import "fmt"

func main() {
   type Person struct {
      Id int
      Name string
   }
   p1 := Person{1,"qwe"}
   p2 := Person{1,"qwe"}
   p3 := Person{Id: 1}
   fmt.Println(p1==p2)
   fmt.Println(p2==p3)
}
--------------------------------------------
true
false

如果结构体包含不可比较的字段,则结构体变量也不可比较。

image-20210223130904334

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值