go语言基础——函数、结构体、接口
由于go不是一门面向对象的语言,因此在有一些特性上和java是有一些区别的,比如go中就没有类这样的概念。下面来介绍一下go的一些特性。
结构体
结构体类似与java中的类,但又不完全一样。在类中,可以定义字段和方法,但是在结构体中是不可以定义方法或者函数的。
定义结构体
下面是一段定义结构体的代码:
package demotype People struct {age intname string
}
其中type
关键字的作用是,表明后面一个东西是一个类型,是什么类型呢?struct
类型。这个类型叫什么名字呢?People
。
当然了,还可以在People
中定义一个结构体:
package demotype People struct {age intname string
}type Student struct {people PeoplestudentId int
}
Student
结构体中有一个People
结构体,除此之外,还包含了一个StudentId
字段。这个例子也多少有那么一点继承的味道吧。
使用
使用结构体的方式也很简单:
package demo
import "fmt"func useStruct() {var people Peoplepeople.age = 10people.name = "people"fmt.Println(people.name)var p1 = People{age: 0,name: "",}fmt.Println(p1)
}
上面people
的类型是People
,如果在一个方法内对传入的people
做修改,外面的是不会受到影响的。如果需要直接访问它本身的话,则需要使用指针结构体(指向结构体的指针)。需要注意的是,只有初始化后才能进行访问,否则会nil。下面两种声明方式是等价的:
var p1 = new(People)
fmt.Println(p1)var p2 = &People{}
fmt.Println(p2)
函数和方法
在go中,函数和方法是两个不同的概念,这也是与java不同的一点。函数可以类比于java中的静态方法,不需要创建一个类就可以直接调用,可以说是相对。对于go来说,一个函数不属于任何结构体和类型,是没有接收者的。与之相对的,方法就是比函数多出来一个接收者。
函数
package demofunc add(a, b) int {return a + b;
}func Add(a, b) int {return a + b;
}
比如上述代码中,add
和Add
就是作为一个函数的身份出现的。需要注意的是,go中没有访问限定符,只是根据函数名首字母的大小写来确定该函数是否能被其他包来使用。比如add
方法不能别其他包来引用,而Add
方法就可以。使用时只需要调用demo.Add(a, b)
就可以了(包名.函数名)。
在java中,要想将一个函数作为参数,只能传一个接口然后去实现它。在go中,可以直接将一个函数作为另一个函数的参数进行传递。
package demofunc twoTimes(a, b int) int {return a + b
}func threeTimes(f func(int, int) int, c int) int {return f(c, c) + c
}
还可以使用别名进行简化:
package demofunc twoTimes(a, b int) int {return a + b
}type tTs func(int, int) intfunc threeTimes(f tTs, c int) int {return f(c, c) + c
}
方法
函数有点独立的感觉,那有时候我们需要让函数和结构体关联起来要怎么做呢?这时候就需要使用方法了。方法是和其接收者——一个结构体绑定在一起的:
package demotype People struct {age intname string
}func (p People) getName() string {return p.name
}
可以这样说,这个getName
成了People
的函数了:
package demofunc useGetName() {var p = new(People)p.getName()
}
需要注意的是,上面getName
方法接受的是People
的一个副本,函数里面的操作不会对原有的p有任何影响。如果想要影响它就需要使用接收者的指针了。
在调用方法的时候,传递的接收者本质上都是副本,只不过一个是这个值副本,一是指向这个值指针的副本。指针具有指向原有值的特性,所以修改了指针指向的值,也就修改了原有的值。我们可以简单的理解为值接收者使用的是值的副本来调用方法,而指针接收者使用实际的值来调用方法。
package demo
func useGetName() {var p = new(People)p.setName("abc")fmt.Println(p) // &{0 }p.setPName("abc")fmt.Println(p) // &{0 abc}
}func (p *People) setName(name string) {p.name = name
}func (p *People) setPName(name string) {p.name = name
}
多值返回
在java中,想要返回多个值只能使用一个类进行包装再返回,而在go中,可以直接返回多个值。在标准库中,经常见到一个函数返回两个值,一个是结果,另一个是错误信息。
func main() {file, err := os.Open("/usr/tmp")if err != nil {log.Fatal(err)return}fmt.Println(file)
}
如果有不想使用的值,那么用_
来进行忽略:
file, _ := os.Open("/usr/tmp")
定义一个多值返回的函数:
package demofunc getPeopleInfo(p People) (string, int) {return p.name, p.age
}
接口
go中的接口也是一组方法的定义,只要一个类型实现了这个接口的所有方法,那么它就是实现了这个接口。只要这个接口声明的方法被全部实现,那么这个接口就可以用了。
package mainimport "fmt"func main() {s := new(student)s.name = "student"c := sfmt.Println(c.onClass())
}type student struct {name string
}type teacher struct {name string
}type classRoom interface {onClass() string
}func (s student) onClass() string {return s.name
}func (t teacher) onClass() string {return t.name
}
当然了,一个类型可以实现多个接口;一个接口也可以被多个类型实现。接口呢,就是说这是一个有这么多方法的一个类型。至于方法是怎么实现的,并不关心。具体的实现是交给结构体和方法去做的。只要能做出来满足这个接口定义的,就全部都可以称之为这个接口类型。
空接口interface{}
可以是任意类型,在go1.18之后的泛型any
本质上就是空接口的别名:type any
。
相关文章:
go语言基础——函数、结构体、接口
由于go不是一门面向对象的语言,因此在有一些特性上和java是有一些区别的,比如go中就没有类这样的概念。下面来介绍一下go的一些特性。 结构体 结构体类似与java中的类,但又不完全一样。在类中,可以定义字段和方法,但…...

项目集管理—项目集治理
一、概述 项目集治理是实现和执行项目集决策,为支持项目集而制定实践,并维持项目集监督的绩效领域。 本章包括: 项目集治理实践项目集治理角色项目集治理设计与实施 项目集治理包括为了满足组织战略和运营目标的要求,对项目集实…...

MySQL了解之复制(一)
1.1、复制解决的问题 数据复制技术有以下一些特点: (1) 数据分布 (2) 负载平衡(load balancing) (3) 备份 (4) 高可用性(high availability)和容错 1.2、复制如何工作 从高层来看,复制分成三步: (1) master将改变记录到二进制…...

Halcon得出三角形内切圆
Halcon得出三角形内切圆 news2023/5/27 7:14: 目录 一、得出三角形的三个角点二、用类似尺规作图法得出三角形圆心 1、以三角形三角点画出圆形轮廓2、求出三角形轮廓与圆形轮廓之间的交点3、获得角平分线,三边角平分线交点为圆心三、求出圆心到边最短距离即半径 …...

2023年6月北京/广州/深圳CDGA/CDGP数据治理认证招生
DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业…...
KMP 算法(Knuth-Morris-Pratt)
tip:作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。 推荐:体系化学习Java(Java面试专题) 文章目录 一、什么是 …...

Java泛型详解
泛型的理解 泛型的概念 所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型 或者是 某个方法的返回值类型及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时&#…...

2023上海国际嵌入式展 | 如何通过人工智能驱动的自动化测试工具提升嵌入式开发效率
2023年6月14日到16日,龙智将在2023上海国际嵌入式展(embedded world China 2023)A055展位亮相。同时,6月14日下午3:00-3:30,龙智资深DevSecOps顾问巫晓光将于创新技术及应用发展论坛第二论坛区(A325展位&am…...

微信小程序个人心得
首先从官方文档给的框架说起,微信小程序官方文档给出了app.js, app.json, app.wxss. 先从这三个文件说起. 复制 app.js 这个文件是整个小程序的入口文件,开发者的逻辑代码在这里面实现,同时在这个文件夹里面可以定义全局变量.app.json 这个文件可以对小程序进行全局配置,决定…...

苹果MacOS系统傻瓜式本地部署AI绘画Stable Diffusion教程
Stable Diffusion的部署对小白来说非常麻烦,特别是又不懂技术的人。今天分享两个一键傻瓜式安装包,对小白来说非常有用。下面两个任选一个安装就可以。 一、DiffusionBee 简单介绍 DiffusionBee是基于stable diffusion的一个安装包,有图形…...
DBA之路-- 闪回恢复区FRA(Flash recovery area)与闪回特性(flashback)[待更新]
闪回恢复区FRA(Flash recovery area)与闪回特性(flashback) 1、闪回特性FB 用于快速简单恢复数据库中出现的认为误操作等逻辑错误 Flashback由undo表空间的撤销段内容为基础,受限于UNDO_RETENTON参数。要使用flashb…...

chatgpt赋能python:Python3.6.5到Python3.7.5:升级指南
Python 3.6.5到Python 3.7.5:升级指南 Python是一种广泛使用的编程语言,拥有强大的库和框架,能够开发各种类型的应用程序。在Python的发行版中,版本更新是常见的过程,以提供更好的性能和新的功能。 本文将介绍如何将…...

Element UI DatePicker 日期选择器
该组件选择周的时候,默认显示‘xxxx年第x周’,但在需求要显示为‘xxxx年x月第x周(mm.dd - mm.dd)’或者‘本周(mm.dd - mm.dd)’,最终效果为 首先需要修改v-model默认展示日期,控件中默认展示为周二&#x…...

sw2urdf导出的urdf文件中的惯性参数(inertial)错误的问题
现象描述 有时候,当我们使用solidworks建好我们的模型,然后利用【sw2urdf】导出后,发现其中的惯性参数,似乎不正确,ixx、izz这些参数都是很接近0的: 资料查找 其实这个不是我们设置的问题,而…...

AICG - Stable Diffusion 学习思考踩坑实录(待续补充)
关于模型 如果模型中没有各种角度的脚和手,无论你再怎么费劲心思,AI 都画不出来,目前C 站也没有什么好脚的例子,正面脚背面脚,但是没有侧面脚,脚这块还是很欠缺,希望未来有大牛能训练出来美脚 …...

LiangGaRy-学习笔记-Day19
1、回顾知识 1.1、文件系统说明 xfs与ext4文件系统 CentOS7以上:默认的就是XFS文件系统 xfs 使用的就是restore、dump等工具 CentOS6默认的就是ext4文件系统 extundelete工具就是用于ext4系统 1.2、回顾Linux文件系统 Linux文件系统是由三个部分组成 inode文…...

智能指针(1)
智能指针(1) 概念内存泄漏指针指针概念RAII使用裸指针存在的问题 智能指针使用分类unique(唯一性智能指针)介绍智能指针的仿写代码理解删除器 概念 内存泄漏 内存泄漏:程序中已动态分配的堆内存由于某些原因而未释放…...

Steemit 会颠覆 Quora/知乎 甚至 Facebook 吗?
Steemit是基于区块链技术的社交媒体平台,其独特的激励机制吸引了众多用户。然而,是否能够真正颠覆Quora、知乎甚至Facebook这些已经成为社交巨头的平台,仍然存在着许多未知因素。本文将探讨Steemit的优势和挑战,以及其在社交领域中…...

002Mybatis初始化引入
引入依赖 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId> </dependency> 自动检测工程中的DataSource创建并注册SqlSessionFactory实例创建并注册SqlSessionTemplate实例自…...

系统架构师之高内聚低耦合
一、概念: 标记耦合(Stamp Coupling)和数据耦合(Data Coupling)是软件设计中两种不同的耦合类型,它们之间的区别如下: 标记耦合:标记耦合是指模块之间通过参数传递标记或标识符来进…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

PH热榜 | 2025-06-08
1. Thiings 标语:一套超过1900个免费AI生成的3D图标集合 介绍:Thiings是一个不断扩展的免费AI生成3D图标库,目前已有超过1900个图标。你可以按照主题浏览,生成自己的图标,或者下载整个图标集。所有图标都可以在个人或…...

向量几何的二元性:叉乘模长与内积投影的深层联系
在数学与物理的空间世界中,向量运算构成了理解几何结构的基石。叉乘(外积)与点积(内积)作为向量代数的两大支柱,表面上呈现出截然不同的几何意义与代数形式,却在深层次上揭示了向量间相互作用的…...