Go语言中的结构体详解

这篇具有很好参考价值的文章主要介绍了Go语言中的结构体详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关于 Golang 结构体

Golang 中没有“类”的概念,Golang 中的结构体和其他语言中的类有点相似。和其他面向对
象语言中的类相比,Golang 中的结构体具有更高的扩展性和灵活性。
Golang 中的基础数据类型可以表示一些事物的基本属性,但是当我们想表达一个事物的全
部或部分属性时,这时候再用单一的基本数据类型就无法满足需求了,Golang 提供了一种
自定义数据类型,可以封装多个基本数据类型,这种数据类型叫结构体,英文名称 struct。
也就是我们可以通过 struct 来定义自己的类型了。

Golang type 关键词自定义类型和类型别名

自定义类型

在 Go 语言中有一些基本的数据类型,如 string、整型、浮点型、布尔等数据类型, Go 语
言中可以使用 type 关键字来定义自定义类型。
type myInt int

上面表示的就是:将 myInt 定义为 int 类型,通过 type 关键字的定义,myInt 就是一种新的类型,

它具有 int 的特性。

类型别名

type TypeAlias = Type
TypeAlias 只是 Type 的别名,本质上 TypeAlias 与 Type 是同一个类型。就像一个孩子小时候有大
名、小名、英文名,但这些名字都指的是他本人。
之前见过的 rune 和 byte 就是类型别名,他们的底层定义如下:
type byte = uint8
type rune = int32

 自定义类型和类型别名的区别

类型别名与自定义类型表面上看只有一个等号的差异,我们可以通过下面的这段代码来理解它们
之间的区别。
package main

import "fmt"

//自定义类型
type myInt int16

//类型别名
type myFloat = float32

func main() {

	var x myInt = 10

	fmt.Printf("%v %T\n", x, x) 

	var y myFloat = 12.3
	fmt.Printf("%v %T", y, y) 
}
Go语言中的结构体详解,# Golang,golang,开发语言,后端 a 的类型是 main.newInt,表示 main 包下定义的 newInt 类型。b 的类型是 int 类型。

结构体定义初始化的几种方法

Go语言中的基础数据类型可以表示一些事物的基本属性,

但是当我们想表达一个事物的全部或部分属性时,

这时候再用单一的基本数据类型明显就无法满足需求了,

Go语言提供了一种自定义数据类型,可以封装多个基本数据类型,

这种数据类型叫结构体,英文名称struct

结构体的定义

使用 type 和 struct 关键字来定义结构体,具体代码格式如下:
type 类型名 struct {
    字段名 字段类型
    字段名 字段类型
}
其中:
类型名:表示自定义结构体的名称,在同一个包内不能重复。
字段名:表示结构体字段名。结构体中的字段名必须唯一。
字段类型:表示结构体字段的具体类型。
package main

import "fmt"

type Car struct{
	name string
	color string
	price int
}

func main() {

	var s1 Car //实例化结构体
	s1.name = "朗逸"
	s1.color = "黑色"
	s1.price = 118000
	fmt.Printf("值:%v 类型:%T\n", s1, s1) 
	fmt.Printf("值:%#v 类型:%T", s1, s1)  
}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

注意:结构体首字母可以大写也可以小写,大写表示这个结构体是公有的,在其他的包里面
可以使用。小写表示这个结构体是私有的,只有这个包里面才能使用。

结构体实例化(第一种方法)

只有当结构体实例化时,才会真正地分配内存。也就是必须实例化后才能使用结构体的字段。
结构体本身也是一种类型,我们可以像声明内置类型一样使用 var 关键字声明结构体类型。
var 结构体实例 结构体类型
package main

import "fmt"

type Car struct{
	name string
	color string
	price int
}

func main() {

	var s1 Car //实例化结构体
	s1.name = "朗逸"
	s1.color = "黑色"
	s1.price = 118000
	fmt.Printf("值:%v 类型:%T\n", s1, s1) 
	fmt.Printf("值:%#v 类型:%T", s1, s1)  
}

结构体实例化(第二种方法)

通过使用 new 关键字对结构体进行实例化,得到的是结构体的地址。

/注意:在 Golang 中支持对结构体指针直接使用.来访问结构体的成员。p2.name = "xx" 其 实在底层是(*p2).name = "xx"

package main

import "fmt"


type Car struct{
	name string
	color string
	price int
}


func main() {

	var s2 = new(Car)
	(*s2).name = "奥迪"
	(*s2).color = "黑色"
	(*&s2.price) = 1000
	fmt.Printf("值:%#v 类型:%T\n", s2, s2)
}
package main

import "fmt"


type Car struct{
	name string
	color string
	price int
}


func main() {

	var s2 = new(Car)
	s2.name = "奥迪"
	s2.color = "黑色"
	s2.price = 1000
	fmt.Printf("值:%#v 类型:%T\n", s2, s2)
}

这两个的写法实质是一样的;就是对开头的一个解释

Go语言中的结构体详解,# Golang,golang,开发语言,后端

从打印的结果中我们可以看出 s2 是一个结构体指针。 

结构体实例化(第三种方法)

使用&对结构体进行取地址操作相当于对该结构体类型进行了一次 new 实例化操作。 

	var s3 = &Car{}
	s3.name = "宝贝马"
	s3.color = "红"
	s3.price = 12000
	fmt.Printf("值:%#v 类型:%T\n", s3, s3)

Go语言中的结构体详解,# Golang,golang,开发语言,后端

结构体实例化(第四种方法)

键值对初始化

    var s3 = Car{
	name : "宝贝马",
	color: "红",
	price:12000,
	}
	fmt.Printf("值:%#v 类型:%T\n", s3, s3)

 注意:最后一个属性的,要加上逗号(键值对的需要加逗号)

结构体实例化(第五种方法)

结构体指针进行键值对初始化
		var s5 = &Car{
		name : "宝贝马",
		color: "红",
		}
		fmt.Printf("值:%#v 类型:%T\n", s5, s5)
当某些字段没有初始值的时候,这个字段可以不写。此时,没有指定初始值的字段的也不写
Go语言中的结构体详解,# Golang,golang,开发语言,后端

结构体实例化(第六种方法)

使用值的列表初始化 

	var s6 = &Car{
	"宝贝马",
	"红",
	100000,
	}
	fmt.Printf("值:%#v 类型:%T\n", s6, s6)

Go语言中的结构体详解,# Golang,golang,开发语言,后端

初始化结构体的时候可以简写,也就是初始化的时候不写键,直接写值: 

使用这种格式初始化时,需要注意:

1.必须初始化结构体的所有字段。
2.初始值的填充顺序必须与字段在结构体中的声明顺序一致。
3.该方式不能和键值初始化方式混用。

结构体是值类型还是引用类型

值类型 : 改变变量副本值的时候,不会改变变量本身的值 (数组、基本数据类型、结构体)

引用类型:改变变量副本值的时候,会改变变量本身的值  (切片、map)

来个案例实验一下:(看副本改变,主体会不会改变)

/*
	值类型 : 改变变量副本值的时候,不会改变变量本身的值 (数组、基本数据类型、结构体)
	引用类型:改变变量副本值的时候,会改变变量本身的值  (切片、map)

*/

package main

import "fmt"


type Car struct{
	Name string
	Color string
	Price int64

}

func main() {
	var s1 = Car{
		"奥迪迦",
		"红",
		187123,
	}

	s2 := s1
	s2.Name = "帕莎特"
	fmt.Printf("%#v\n", s1) 
	fmt.Printf("%#v", s2) 


}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

 结构体是值类型,改变副本不会改变其主的内存值

结构体方法和接收者

在 go 语言中,没有类的概念但是可以给类型(结构体,自定义类型)定义方法。所谓方法
就是定义了接收者的函数。接收者的概念就类似于其他语言中的 this 或者 self。
方法的定义格式如下:
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
    函数体
}
其中
接收者变量:接收者中的参数变量名在命名时,官方建议使用接收者类型名的第一个小
写字母,而不是 self、this 之类的命名。
例如,Person 类型的接收者变量应该命名为 p,Connector 类型的接收者变量应该命名为 c 等。
接收者类型:接收者类型和参数类似,可以是指针类型和非指针类型。
方法名、参数列表、返回参数:具体格式与函数定义相同。

值类型的接收者

当方法作用于值类型接收者时, Go 语言会在代码运行时将接收者的值复制一份。在值类型
接收者的方法中可以获取接收者的成员值,但修改操作只是针对副本,无法修改接收者变量
本身。

package main

import "fmt"


 type Car struct{
	Name string
	Color string
	Price int32

 }

 func (c Car) PrintInfo(){
	fmt.Printf("车辆名称:%v 颜色为:%v 价格为:%v\n",c.Name,c.Color,c.Price)
 }

func main() {

	var c1 = new(Car)
	c1.Name = "奥托"
	c1.Color = "黑"
	c1.Price = 123423
	c1.PrintInfo()

	var c2 = Car{
		"斑马",
		"红",
		123143,
	}
	c2.PrintInfo()
	
}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

指针类型的接收者

指针类型的接收者由一个结构体的指针组成,由于指针的特性,调用方法时修改接收者指针

的任意成员变量,在方法结束后,修改都是有效的。这种方式就十分接近于其他语言中面向
对象中的 this 或者 self。

package main

import "fmt"


 type Car struct{
	Name string
	Color string
	Price int32

 }

 func (c Car) PrintInfo(){
	fmt.Printf("车辆名称:%v 颜色为:%v 价格为:%v\n",c.Name,c.Color,c.Price)
 }

 func (c1 *Car) SetInfo(name string,color string){
	c1.Name = name
	c1.Color = color
 }
func main() {

	var c1 = new(Car)
	c1.Name = "奥托"
	c1.Color = "黑"
	c1.Price = 123423
	c1.PrintInfo()

	var c2 = Car{
		"斑马",
		"红",
		123143,
	}
	c2.PrintInfo()

	c1.SetInfo("宝贝马","绿")
	c1.PrintInfo()


	
}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

给任意类型添加方法

Go 语言中,接收者的类型可以是任何类型,不仅仅是结构体,任何类型都可以拥有方法。
举个例子,我们基于内置的 int 类型使用 type 关键字可以定义新的自定义类型,然后为我们
的自定义类型添加方法。

package main

import "fmt"

//注意事项: 非本地类型不能定义方法,也就是说我们不能给别的包的类型定义方法。
type MyInt int

func (m MyInt) PrintInfo() {
	fmt.Println("我是自定义类型里面的自定义方法")
}

func main() {

	var a MyInt = 20

	a.PrintInfo()
}
注意事项: 非本地类型不能定义方法,也就是说我们不能给别的包的类型定义方法

结构体的匿名字段 

结构体允许其成员字段在声明时没有字段名而只有类型,这种没有名字的字段就称为匿名字段

匿名字段默认采用类型名作为字段名,结构体要求字段名称必须唯一,因此一个结构体中同种类型的匿名字段只能有一个

案例如下:
package main

import "fmt"

type Car struct{
	string
	int
}

func main() {

	c := Car{
		"法拉奔",
		123123,
	}
	fmt.Printf("汽车品牌:%v,价格为:%v",c.string,c.int)
}
Go语言中的结构体详解,# Golang,golang,开发语言,后端

嵌套结构体

一个结构体中可以嵌套包含另一个结构体或结构体指针

结构体的字段类型可以是:基本数据类型、也可以是切片、Map 以及结构体

如果结构体的字段类型是: 指针,slice,和map的零值都是 nil ,即还没有分配空间

如果需要使用这样的字段,需要先make,才能使用.

嵌套指针;映射

案例如下:

package main

import "fmt"

type Car struct{
	Name string
	Price int
	Seller []string
	Buyer map[string]string
}

func main() {

	var c Car
	c.Name = "宝贝马"
	c.Price = 1231334
	c.Seller = make([]string,3,10) // 指针,slice,和map的零值都是 nil ,即还没有分配空间;如果需要使用这样的字段,需要先make,才能使用.
	c.Seller[0] = "卫宫士郎"
	c.Seller[1] = "远坂樱"
	c.Seller[2] = "鸣人"
	c.Buyer = make(map[string]string)
	c.Buyer["宫本"] = "已购"
	c.Buyer["宋璇"] = "已购"
	fmt.Printf("%#v\n",c)
	fmt.Println("----------------------------")
	fmt.Printf("%v\n",c.Buyer)



}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

 结构体嵌套

package main

import "fmt"

/*
结构体嵌套
*/
type Person struct{
	Name string
	Age int
	Infomation 
}

type Infomation struct{
	Address string
	Country string
}

func main() {


	var p Person
	p.Name = "奥特曼"
	p.Age = 21
	p.Infomation.Address = "m78"
	p.Infomation.Country = "光"
	
	fmt.Printf("%#v",p)




}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

嵌套匿名结构体 

package main

import "fmt"

type Person struct{
	Name string
	Age int
	Infomation
}

type Infomation struct{
	City string
	Country string
}

func main() {
	var a Person
	a.Name = "奥特曼"
	a.Age = 12
	a.Country = "M78"
	a.City = "光"
	fmt.Printf("%v\n", a)
	fmt.Printf("%#v\n", a)
	fmt.Println(a.Infomation.City)
}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

//当访问结构体成员时会先在结构体中查找该字段,找不到再去匿名结构体中查找。 

比如上面的,我们可以直接在a中赋值information的数据
Go语言中的结构体详解,# Golang,golang,开发语言,后端
package main

import "fmt"
type Person struct{
	Name string
	Age int
	Hobby string
	Infomation
}

type Infomation struct{
	City string
	Country string
	Hobby string
}

func main() {
	var a Person
	a.Name = "奥特曼"
	a.Age = 12
	a.Country = "M78"
	a.City = "光"
	a.City = "日本" //当访问结构体成员时会先在结构体中查找该字段,找不到再去匿名结构体中查找。
	a.Hobby = "唱跳"
	a.Infomation.Hobby = "睡觉"
	fmt.Printf("%#v\n", a)
	

}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

 关于嵌套结构体的字段名冲突

嵌套结构体内部可能存在相同的字段名。这个时候为了避免歧义需要指定具体的内嵌结构体的字段。
package main

import "fmt"

type Persion struct{
	Name string
	// Hobby string
	Information
	Realation
	
}
type Information struct{
	Hobby string
}
type Realation struct{
	Hobby string
}

func main() {

	var p Persion
	p.Name = "奥特"
	p.Hobby = "唱跳"
	fmt.Printf("%#v\n", p)
	

}

Go语言中的结构体详解,# Golang,golang,开发语言,后端

找不到是哪个结构体内的hobby


	var p Persion
	p.Name = "奥特"
	// p.Hobby = "唱跳"
	p.Information.Hobby= "唱跳"
	fmt.Printf("%#v\n", p)

Go语言中的结构体详解,# Golang,golang,开发语言,后端

 结构体的继承

Go 语言中使用结构体也可以实现其他编程语言中的继承。

package main

import "fmt"

//父结构体
type Faher struct{
	Name string
}
 
func (a Faher) fn1(){
	fmt.Printf("%v发动x射线\n",a.Name)
}
//子结构体
type Son struct{
	Fight string
	Faher //结构体嵌套 继承
}
func (s Son) fn2(){
	fmt.Printf("%v超人飞踢",s.Name)
}
func main() {
	var c = Son{
		Faher: Faher{
			Name: "奥托之父",
		},
	}
	c.fn1()
	c.fn2()
}

 指针类型

Go语言中的结构体详解,# Golang,golang,开发语言,后端文章来源地址https://www.toymoban.com/news/detail-616730.html

package main

import "fmt"

//父结构体
type Faher struct{
	Name string
}
 
func (a Faher) fn1(){
	fmt.Printf("%v发动x射线\n",a.Name)
}
//子结构体
type Son struct{
	Fight string
	*Faher //结构体嵌套 继承
}
func (s Son) fn2(){
	fmt.Printf("%v超人飞踢",s.Name)
}
func main() {
	var c = Son{
		Faher: &Faher{
			Name: "奥托之父",
		},
	}
	c.fn1()
	c.fn2()
}

到了这里,关于Go语言中的结构体详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 100天精通Golang(基础入门篇)——第5天: Go语言中的数据类型学习

    🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批

    2024年02月08日
    浏览(44)
  • Golang 中的 io 包详解(五):结构体类型介绍

    实现了 io.Reader 接口,并且进行了功能扩展。R 表示 io.Reader 对象,N 表示最多允许读取的字节数。简单示例如下所示: 当读取的字节数超过限制时,LimitedReader 会自动终止读取并返回一个 io.EOF 错误,表示已经达到了总字节数的限制。 实现了 io.Reader、io.ReaderAt 和 io.Seeker 接口

    2024年02月08日
    浏览(43)
  • 【Golang星辰图】数据管理利器:Go编程语言中的数据库和搜索引擎综合指南

    Go编程语言是一种强大、类型安全且高效的编程语言,它在处理数据库和搜索引擎方面有着广泛的应用。本篇文章将详细介绍几个Go编程语言中常用的数据库和全文搜索引擎,包括Go-bleve、Go-pgx、Go-leveldb/leveldb、Go-xorm、Go-mysql-driver和Go-bbolt/bbolt。对于每个工具,我们将介绍其功

    2024年03月26日
    浏览(67)
  • 100天精通Golang(基础入门篇)——第12天:深入解析Go语言中的集合(Map)及常用函数应用

    🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批

    2024年02月12日
    浏览(47)
  • 【Golang】Golang进阶系列教程--Go 语言数组和切片的区别

    在 Go 语言中,数组和切片看起来很像,但其实它们又有很多的不同之处,这篇文章就来说说它们到底有哪些不同。 数组和切片是两个常用的数据结构。它们都可以用于存储一组相同类型的元素,但在底层实现和使用方式上存在一些重要的区别。 Go 中数组的长度是不可改变的

    2024年02月15日
    浏览(57)
  • 【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?

    在 Go 语言中,有一个很常用的数据结构,那就是切片(Slice)。 切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。 切片是一种引用类型,它有三个属性:指针,长度和容量。 底层源码定义如下: 指针: 指向

    2024年02月14日
    浏览(63)
  • 【Golang】Golang进阶系列教程--Go 语言 map 如何顺序读取?

    Go 语言中的 map 是一种非常强大的数据结构,它允许我们快速地存储和检索键值对。 然而,当我们遍历 map 时,会有一个有趣的现象,那就是输出的键值对顺序是不确定的。 先看一段代码示例: 当我们多执行几次这段代码时,就会发现,输出的顺序是不同的。 首先,Go 语言

    2024年02月14日
    浏览(65)
  • golang实现webgis后端开发

    目录 前言 二、实现步骤 1.postgis数据库和model的绑定 2.将pg库中的要素转换为geojson (1)几何定义 (2)将wkb解析为几何类型 (3)定义geojson类型 (4)数据转换 (5)数据返回  2.前端传入的geojson储存到数据库 3、其他功能实现 总结         停更了接近一个月都在研究一门新语言gola

    2024年02月08日
    浏览(49)
  • 【Golang中的Go Module使用】

    Golang中的Go Module是一个用于包管理和版本控制的工具。在本文中,我们将深入探讨Go Module的相关知识,包括其定义、使用方法以及一些常见的应用场景。 Go Module是Golang中的包管理和版本控制工具,它的发展历程、用法、意义以及相关指令都对于Golang开发者来说非常重要。在本

    2024年02月16日
    浏览(46)
  • 【Golang】VScode配置Go语言环境

    安装VScode请参考我的上一篇博客:VScode安装_㫪548的博客-CSDN博客 接下来我们直接进入正题: Go语言(又称Golang)是一种开源的编程语言,由Google开发并于2009年首次发布。Go语言具有简洁、高效、可靠和易于阅读的特点,被设计用于解决大型项目的开发需求。它结合了静态类型

    2024年02月03日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包