Go 结构体

目录

什么是结构体

定义结构体

基本的方式实例化结构体

访问结构体的成员变量

指针类型的方式实例化结构体

取结构体地址的方式实例化

知识扩展:*号 和 &号

构造函数

成员函数(成员方法)

匿名成员变量

方法传入指针类型的结构体

结构体嵌套

深拷贝与浅拷贝


什么是结构体

  • Go 语言通过用自定义的方式形成新的类型,结构体是类型中带有成员的复合类型。Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性。
  • Go 语言中的结构体类型可以被实例化,使用new&构造的类型实例的类型是类型的指针。
  • 结构体成员是由一系列的成员变量构成,这些成员变量也被称为“字段”。字段有以下特性:
    • 字段拥有自己的类型和值。
    • 字段名必须唯一。
    • 字段的类型也可以是结构体,甚至是字段所在结构体的类型。
  • 关于 Go 语言的类(class)
    • Go 语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念。
    • Go 语言的结构体与“类”都是复合结构体,但 Go 语言中结构体的内嵌配合接口比面向对象具有更高的扩展性和灵活性。
    • Go 语言不仅认为结构体能拥有方法,且每种自定义类型也可以拥有自己的方法。

定义结构体

自定义的结构体名称在同一个包内不允许重复。结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正地分配内存,因此必须在定义结构体并实例化后才能使用结构体的字段。

语法

// type 关键字表示定义普通结构体

// 把 type 关键字换成 var 表示定义的是匿名结构体,匿名结构体通常用于只使用一次的情况

type 自定义结构体名称 struct {

        字段1 数据类型

        字段n 数据类型

}

示例

// type 和 struct 是定义结构体的关键字 
type user struct {
	// id
	id int64
	// 生日
	birthday time.Time
	// 账号,密码,姓名
	account, password, username string //  类型相同的字段可以简写在同一行
}

基本的方式实例化结构体

实例化就是根据结构体定义的格式创建一份与格式一致的内存区域,结构体实例与实例间的内存是完全独立的。

语法

var 自定义的变量名称 结构体名称

示例

var u user    //声明,  结构体中的每一个字段,都会被相应的类型的默认值初始化

u = user{}    //结构体中的每一个字段,都会被相应的类型的默认值初始化

u = user{id: 1, account: "ZhangSan"}    // 初始化时赋值

u = user{1, time.Now(), "ZhangSan", "123456", "张三"}    // 赋值初始化时可以省略字段名,但是需要与结构体定义里的字段顺序保持一致

访问结构体的成员变量

使用.来访问结构体的成员变量

示例

u.id
u.username
u.account

指针类型的方式实例化结构体

Go语言中,还可以使用 new 关键字对类型(包括结构体、整型、浮点数、字符串等)进行实例化,结构体在实例化后会形成指针类型的结构体。

示例

var u = new(user)
fmt.Println(u.id)
u.password = "654321"

 注:u 的类型属于 *user,属于指针类型。


取结构体地址的方式实例化

在Go语言中,对结构体进行&取地址操作时,视为对该类型进行一次 new 的实例化操作。

示例

// 定义一个结构体
type command struct {
	Name string // 名称
	Var  *int   // 绑定的变量,使用整型指针绑定一个指针,变量值可以与绑定的值随时保持同步
}

var version int = 1 //绑定的目标变量

cmd := &command{}  // 对结构体取地址实例化
cmd.Name = "haha"  // 初始化成员变量
cmd.Var = &version // 初始化成员变量

知识扩展:*号 和 &号

变量是什么?变量是一块内存的别名,即给这块内存起一个名字,这块内存在计算机内存中有具体的地址。

&:取地址符号,表示取出这个变量所在内存的地址。

*:指针符号,表示指向变量的内存地址。指针变量就是指向内存地址的变量

*是指,&是取,可以理解成 &取得的值赋给*,即  *p = &a

一个变量由变量地址和地址上的数据组成,在内存中物理表示的方式如下图

例如

var a = 10
var p *int                   // 第 2 行
p = &a

fmt.Printf("%T \n", p) // *int

fmt.Println(&a) // 0xc00001e0a8
fmt.Println(p)  // 0xc00001e0a8

fmt.Println(a)   // 10
fmt.Println(*&a) // 10        // &a = p,那么是不是 *&a 和 *p 是一样的
fmt.Println(*p)  // 10        // 第 10 行

// 注意第2行和第10行*号的区别,第2行表示这是一个指针变量,第10行表示取这个指针地址上的数据

构造函数

Go语言的类型或结构体没有构造函数的功能,可以使用结构体初始化的过程来模拟实现构造函数。

示例

// Cat 定义结构体
type Cat struct {
	Color string
	Name  string
}

// NewCatByName 定义构造函数,只初始化名称
func NewCatByName(name string) *Cat {
	return &Cat{
		Name: name,
	}
}

// NewCatByColor 定义构造函数,只初始化颜色
func NewCatByColor(color string) *Cat {
	return &Cat{
		Color: color,
	}
}

// 调用构造函数,生成构造实例
var c = NewCatByName("大花")
fmt.Println(c.Name)

注:返回 * 指针类型,和返回普通构造类型的区别在于对象流转在内存中是通过拷贝进行的,返回普通构造类型拷贝的是对象的实例数据,返回指针的话只用拷贝对象的地址(一个int32的数值)


成员函数(成员方法)

成员方法可以写在不同的文件中,但是必须是在一个包下面。

语法

func (结构体实例 结构体类型) 方法名(入参) 返回类型 {

        方法体

}

示例

type user struct {
	id int64
	birthday time.Time
	account, password, username string
}
// 成员方法,如果是(_ user) 或者 (user) 表示匿名成员方法
func (u user) hello(man string) {
	fmt.Println("你好 " + man + ",我的名字是 " + u.username)
}

// 调用成员方法
var u = user{username: "ZhangSan"}
u.hello("LiSi")

匿名成员变量

匿名字段,直接使用类型作为字段名,所以匿名字段中不能出现重复的数据类型。

示例

// 定义
type Student struct {
	id      int
	string  // 匿名字段
	float32 // 匿名字段
}

// 使用
var stu = Student{id: 1, string: "ZhangSan", float32: 88.3}
fmt.Println(stu.string)

方法传入指针类型的结构体

  • 方法入参是普通的结构体时,在函数里修改入参结构体对象不影响原来的结构体数据。因为传入的是数据的拷贝,不影响原来的数据。(深拷贝)
  • 方法入参是指针类型的结构体时,在函数里修改入参结构体对象时,会影响原来的结构体数据,因为传入的是指针,修改会直接修改指针地址上的数据。(浅拷贝)

示例

func hello(u *user) {
	u.username = "LiSi"
}

func (u *user) hello() {
	u.username = "LiSi"
}

结构体嵌套

示例

type user struct {
	name string
}

type book struct {
	name   string
	author user
}

func main() {
	b := new(book)
	b.name = "三国演义"
	b.author.name = "罗贯中"
}

深拷贝与浅拷贝

深拷贝:会拷贝元素的整个内存空间的数据,把数据赋值给另一块内存空间,修改数据互不影响。

浅拷贝:只拷贝元素的内存地址,拷贝完成后修改新的元素,会影响原来的元素,传slice数浅拷贝。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/4132.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mac M1通过VMWare Fusion安装Centos7记录(镜像和网络有大坑)

以前用linux系统基本都在我的服务器上或者是在win上进行,从没有在M1上进行创建,因此走了一些坑吧,这里会列出我的详细安装步骤。 下载镜像 镜像的下载网站:https://www.centos.org/download/ 在该网站中,不管是Every…

多级评论单表结构设计

这里的多级,本质上其实也就二级,例如微博的评论, 一级评论: 对微博的评论 二级评论: 对微博下的评论的回复评论 ,这里包括二种 1. 回复的是一级评论, 2, 回复的是二级评论 效果如下 表数据 查…

基于微信小程序的图书馆选座系统源码

开发环境及工具: 大等于jdk1.8,大于mysql5.5,idea(eclipse),微信开发者工具 技术说明: springboot mybatis 小程序 代码注释齐全,没有多余代码,适合学习(…

Android Studio模拟器运行无反应

当Android Studio模拟器点击运行无反应 报以下错误: Emulator: PANIC: Cannot find AVD system path. Please define ANDROID_SDK_ROOT 问题分析 大多是由于默认路径带有中文,所以找不到 解决方法 1,删除镜像 2,配置环境变量 …

Unity强化学习之ML-Agents的使用

Github下载链接:https://github.com/Unity-Technologies/ml-agents ML-Agents是游戏引擎Unity3D中的一个插件,也就是说,这个软件的主业是用来开发游戏的,实际上,它也是市面上用得最多的游戏引擎之一。而在几年前随着人…

Maven配置—idea版

在java开发中,maven是个不可或缺的工具,可以简单理解成maven是个仓库,可以远程下载各种需要的插件,而且对于项目的打包编译等也非常简单;下面来说说如何配置maven 1. 首先下载maven的工具包,解压之后放在D…

OCR之论文笔记TrOCR

文章目录TrOCR: Transformer-based Optical Character Recognition with Pre-trained Models一. 简介二. TrOCR2.1. Encoder2.2 Decoder2.3 Model Initialiaztion2.4 Task Pipeline2.5 Pre-training2.6 Fine-tuning2.7 Data Augmentation三. 实验3.1 Data3.2 Settings3.2 Resul…

测试用例设计指南

作者:京东物流 王玉坤 软件测试设计是测试过程中重要的测试活动,怎么样设计测试用例能提高我们测试的效率和质量,从以下几个方面做了简单的讲解。 1 测试用例设计原则 测试用例设计的基本原则包括:有效性、清晰性、可复用性、可维…

Linux 0.11

调试介绍 Linux 0.11-调试 Linux 最早期的代码-36 启动跟踪 BIOS 加载 电脑启动,CPU指向0xFFFFFFF0处,这里正好是系统ROM BIOS存放的地址。即开始执行BIOS指令。为了保持向下兼容,就会把与原PC兼容的BIOS代码和数据复制到低端1M末端的64K…

0基础实现微信推送天气,生日等(女朋友快乐眼)

最近微信小程序推送的功能很火,我也是去看了很多攻略,最后选了一个0基础的版本,最后也是实现了推送功能,如图 如何实现? 首先,打开微信官方提供的一个接口生成网址,微信扫码登录,然…

数据挖掘(作业汇总)

目录 环境配置 实验1 数据 作业2 环境配置 实验开始前先配置环境 以实验室2023安装的版本为例: 1、安装anaconda:(anaconda自带Python,安装了anaconda就不用再安装Python了) 下载并安装 Anaconda3-2022.10-Windows-x86_64.ex…

剑指offer JZ77 按之字形顺序打印二叉树

Java JZ77 按之字形顺序打印二叉树 文章目录Java JZ77 按之字形顺序打印二叉树一、题目描述二、双栈法三、队列reverse()法使用双栈法和队列reverse()法解决剑指offer JZ77 按之字形顺序打印二叉树的问题。 一、题目描述 给定一个二叉树,返回该二叉树的之字形层序遍…

【pytorch】深度学习模型调参策略(五):采用贝叶斯工具进行最优参数搜索及最佳步数确认

目录1.如何决定是否应用某个新的超参数配置2.参数优化工具optuna确定最终最优配置为什么在调整的探索阶段使用准随机搜索而不是更复杂的黑盒优化算法?optuna库简介pytorch实现代码搜索参数详解输出结果3.确定每次训练运行的步数使用学习率扫描选择max_train_steps初…

设置鼠标右键打开方式,添加IDEA的打开方式

一、问题描述 已下载IDEA,但是右键打开之前保存的项目文件,无法显示以IDEA方式打开。 二、解决步骤 1. 打开注册表 winR键输入regedit 2、查找路径为计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell (我找了半天没看到Class…

在芯片设计行业,从项目的初期到交付,不同的岗位的工程师主要负责什么?

大家都知道在芯片设计行业,项目是至关重要的一环。从项目的初期到交付,不同的岗位的工程师在项目的各环节主要负责什么?他们是怎样配合的?下面看看资深工程师怎么说。 一个项目,从初期到交付的过程是比较漫长的。我们知道最早的时候&#…

deskvideosys 办公行为管理软件的部署架构

deskvideosys 办公行为管理软件服务器端使用的是 B/S 架构,采用 golangvue 框架来编程,agent 端直接使用的是 vc编程框架,然后通过tcp协议连接服务器端,所以deskvideosys架构 可以作为终端安全管理,上网行为管理&#…

小程序 table组件

最近有在小程序中用table的需求,但是没有找到有符合要求的组件,所以自己弄了一个,能满足基本需求。 组件下载:https://download.csdn.net/download/weixin_67585820/85047405 引入 "usingComponents": {"table": "…

基于springboot和Web实现社区医院管理服务系统【源码+论文】分享

基于springboot和Web的社区医院管理服务系统演示开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Mave…

记录--Vue 3 中的极致防抖/节流(含常见方式防抖/节流)

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 今天给大家带来的是Vue 3 中的极致防抖/节流(含常见方式防抖/节流)这篇文章,文章中不仅会讲述原来使用的防抖或节流方式,还会带来新的一种封装方式,使用起来更简单、…

diffusion 之 cifar/mnist 数据集

diffusion 之 mnist 数据集mnist数据集ddpm/script_utils.pyscripts/train_mnist.py展示采样结果代码出处:https://github.com/abarankab/DDPMwandb的问题解决方法: step1: 按照这个https://blog.csdn.net/weixin_43164054/article/details/1…