第七章结构体

结构体

定义结构体

Go语言中通过关键字type定义自定义类型,结构体定义需要使用type和struct关键字,具体定义格式如下:

type 结构体名 struct  {
							成员变量1  类型1
							成员变量2  类型2
							成员变量3  类型3 
							...
}

注意:

  • 结构体名:同一个包内结构体名不可以重复。
  • 成员名:同一个结构体内,成员名不能重复。
  • 类型1、类型2…:表示结构体成员变量的类型。
  • 同类型的成员名可以写在同一行。
  • 当结构体、方法名或变量名的首字母为大写时(可被导出),就可以在当前包外进行访问。

例如:

type Book struct {
		title string
		author string
		num int
		id int
		}

实例化结构体

一个结构体在定义完成后才能进行。结构体实例化时,会真正地分配内存。因此必须在定义结构体并实例化后才能使用结构体的字段。Go语言实例化结构体主要有以下三种方式:

  • 标准实例化
  • new函数实例化
  • 取地址实例化

标准实例化

var 结构化实例 结构体类型

例如:

package main

import "fmt"

type Book struct {
		title string
		author string
		num int
		id int 
}

func main() {
		var book Book
		fmt.Println(book)
}

new函数实例化

  • new函数可对结构体进行实例化,实例化完成后会返回结构体的指针类型
package main

import "fmt"

type Book struct {
		title string
		author string
		num int
		id int 
}
func main() {
		book := new(Book)
		fmt.Println(book)
}

取地址实例化

  • 取地址实例化与使用new函数进行实例化类似,返回的是结构体指针类型。取地址实例化格式如下:
package main

import "fmt"

type Book struct {
		title string
		author string
		num int
		id int 
}

func main() {
		book := &Book{}
		fmt.Println(book)
}

访问成员

结构体实例化后,可以通过“.”来访问结构体成员变量,对成员变量进行赋值或修改。

package main

import "fmt"

type Book struct {
		title string
		author string
		num int
		id int 
}

func main() {
		book := &Book{}
		book.title= "Go语言"
		book.author= "Tom"
		book.num= 20
		book.id= 123
		fmt.Println("title:",book.title)
		fmt.Println("author:",book.author)
		fmt.Println("num:",book.num)
		fmt.Println("id:",book.id)
}

初始化结构体

键值对格式初始化

结构体实例 := 结构体类型{
			成员变量1:1,
			成员变量2:2,
			成员变量3:3,
			...
}

这种类型的初始化类似于对map数据类型的初始化操作,键和值之间以冒号分隔,键值对之间以逗号分隔。

package main

import "fmt"

type Book struct {
		title string
		author string
		num int
		id int 
}

func main() {
		book := &Book{
				title:  "Go语言",
				author:  "Tom",
				num: 20,
				id: 123}
		fmt.Println("title:",book.title)
		fmt.Println("author:",book.author)
		fmt.Println("num:",book.num)
		fmt.Println("id:",book.id)
}

列表格式初始化

结构体实例 := 结构体类型{1,
		值2,
		值2}

注意:

  • 使用这种方式初始化结构体必须初始化所有的成员变量。
  • 值得填充顺序必须和结构体成员变量声明的顺序保持一致。
  • 该方式与键值对的初始化方式不能混用。
package main

import "fmt"

type Book struct {
		title string
		author string
		num int
		id int 
}

func main() {
		book := &Book{
				"Go语言""Tom"20123}
		fmt.Println("title:",book.title)
		fmt.Println("author:",book.author)
		fmt.Println("num:",book.num)
		fmt.Println("id:",book.id)
}

结构体方法

Go语言中,一个方法就是一个包含了接收者的函数。对于结构体方法,接收者可以是结构体类型的值或者指针。

指针类型接收者

当接收者类型为指针时,可以通过该方法改变接收者的成员变量值,即使你使用了非指针类型实例调用该函数,也可以改变对应的成员变量值。

package main

import "fmt"

type User struct {
		Name string
		Email string
}

func (u *User) ChangName() { //指针类型接收者
		u.Name= "Tom"
}

func main() {
		u := &User {"Peter", "go@go.com"} //创建指针类型结构体实例
		fmt.Println("Name:",u.Name,"Email:",u.Email)
		u.ChangName()
		fmt.Println("Name:",u.Name,"Email:",u.Email)
}

或者

package main

import "fmt"

type User struct {
		Name string
		Email string
}

func (u *User) ChangName() { //指针类型接收者
		u.Name= "Tom"
}

func main() {
		u := User {"Peter","go@go.com"} //创建非指针类型结构体实例
		fmt.Println("Name:",u.Name,"Email:",u.Email)
		u.ChangName()
		fmt.Println("Name:",u.Name,"Email:",u.Email)
}

执行结果:

Name: Peter Email: go@go.com
Name: Tom   Email: go@go.com

值类型接收者

当接收者不是一个指针时,该方法的操作对应接收者的副本,否则即使你使用了指针调用函数,也无法改变成员变量值。

package main

import "fmt"

type User struct {
		Name string
		Email string
}

func (u User) ChangName() { //值类型接收者
		u.Name= "Tom"
}

func main() {
		u := &User {"Peter", "go@go.com"} //创建指针类型结构体实例
		fmt.Println("Name:",u.Name,"Email:",u.Email)
		u.ChangName()
		fmt.Println("Name:",u.Name,"Email:",u.Email)
}

执行结果:

Name: Peter  Email:go@go.com
Nmae: Peter  Email:go@go.com

结构体内嵌

Go语言的结构体内嵌是一种组合特性,使用结构体内嵌可构建一种面向对象编程思想中的继承关系,结构体实例化后,可直接访问内嵌结构体的所有成员变量和方法。

type 结构体名1 struct {
		成员变量1 类型1
		成员变量2 类型2
}

type 结构体名2 struct {
		结构体名1
		成员变量3 类型3
}
package main

import "fmt"

type Book struct {
	 title string
	 author string
	 num int 
	 id int
}

type BookBorrow struct
{
	Book
	borrowTime string
}

type BookNotBorrow struct
{
	Book
	readTime string
}

func main() {
	bookBorrow := &BookBorrow{}
	bookNotBorrow := &BookNotBorrrow{}
	fmt.Println(bookBorrow)
	fmt.Println(bookNotBorrow)
}

初始化结构体内嵌

结构体内嵌的初始化和结构体初始化类似,可以使用键值对或“.”的方式来进行初始化

type 结构体名1 struct {
		成员变量1 类型1
		成员变量2 类型2
}

type 结构体名2 struct {
		结构体名1
		成员变量3 类型3
}
package main

import "fmt"

type Book struct {
	 title string
	 author string
	 num int 
	 id int
}

type BookBorrow struct
{
	Book
	borrowTime string
}

type BookNotBorrow struct
{
	Book
	readTime string
}

func main() {
	bookBorrow := &BookBorrow{
			Book:Book{"Go语言",
			"Tom",
			20,
			152358,
			},
			borrowTime:"30",
}
	fmt.Println(boookBorrow)
	bookNotBorrow := &BookNotBorrrow{
	}
	bookNotBorrow.title="Python语言"
	bookNotBorrow.author="Peter"
	bookNotBorrow.num=10
	bookNotBorrow.id=152359
	bookNotBorrow.readTime="50"
	fmt.Println(bookNotBorrow)
}

执行结果如下:

&{{Go语言 Tom 20 152358} 30}
&{{Python语言 Peter 10 152359} 50}

内嵌匿名结构体

在定义匿名结构体时,无须type关键字,但是在初始化被嵌入的匿名结构体时,需要再次声明结构体才能赋予数据

package main

import "fmt"

type BookBorrow struct {
	 Book struct { //内嵌匿名结构体
	 		title string
	 		author string 
	 		num int 
	 		id num
	 		}
	 		borrowTime string
}

func main() {
	 bookBorrow := &BookBorrow{
	 	 Book:struct { //声明类型
	 	 	title string
	 	 	author string
	 	 	num int
	 	 	id num
	 	 	}{	"Go语言",
	 	 		"Tom",
	 	 		20,
	 	 		152358,
	 	 		},
	 	 		borrowTime:"30",
	 	 	}
	 	 	fmt.Println(bookborrow)
}

匿名结构体

匿名结构体定义与初始化

title: Go语言
结构体实例 := struct{
	//匿名结构体定义
	成员变量1 类型1
	成员变量2 类型2
	成员变量3 类型3
	...
	}{
		//成员变量初始化(可选)
		成员变量1:值1,
		成员变量2:值2,
		成员变量3:值3...
}

匿名结构体的应用

匿名结构体一般用于组织全局变量、构建数据模板和解析JSON等

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值