Golang简易入门教程——面向对象篇
本文始发于个人公众号:TechFlow,原创不易,求个关注
今天是golang专题的第9篇文章,我们一起来看看golang当中的面向对象的部分。
在现在高级语言当中,面向对象几乎是不可或缺也是一门语言最重要的部分之一。golang作为一门刚刚诞生十年的新兴语言自然是支持面向对象的,但是golang当中面向对象的概念和特性与我们之前熟悉的大部分语言都不尽相同。比如Java、Python等,相比之下, golang这个部分的设计非常得简洁和优雅(仁者见仁),所以即使你之前没有系统地了解过面向对象,也没有关系,也一定能够看懂。
常见的面向对象的部分,比如继承、构造函数、析构函数,这些内容在golang当中统统没有,因此整体的学习成本和其他的语言比起来会更低一些。
struct
在golang当中没有类的概念,代替的是结构体(struct)这个概念。我们可以给结构体类型定义方法,为了表明该方法的适用对象是当前结构体,我们需要在方法当中定义接收者,位于func关键字和方法名之间。
我们一起来看一个例子:
type Point struct {
x int
y int
}
func (p Point) Dis() float64 {
return math.Sqrt(float64(p.x*p.x + p.y*p.y))
}
在上面这段代码当中我们定义了一个叫做Point的结构体,以及一个面向这个结构体的方法Dis。我们一个一个来看它们的语法。
对于结构体来说,我们通过type关键字定义。在golang当中type关键字的含义是定义一个新的类型。比如我们也可以这样使用type:
type Integer int
它的含义是从int类型定义了一个新的类型Integer,从此之后我们可以在后序的代码当中使用Integer来代替int。它有些类似于C++当中的typedef,结合这个含义,我们再来看结构体的定义就很好理解了。其实是我们通过struct关键字构造了一个结构体,然后使用type关键字定义成了一个类型。
之后我们创建了一个面向结构体Point的函数Dis,这个函数和我们之前使用的函数看起来并没有太多的不同,唯一的区别在于我们在func和函数名之间多了一个(p Point)的定义。这其实是定义这个函数的接收者,也就是说它接受一个结构体的调用。
不仅如此,我们可以给golang当中的任何类型添加方法,比如:
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
在这个例子当中,我们给原生的int类型添加了Less这个方法,用来比较大小。我们在添加方法之前使用type给int起了一个别名,这是因为golang不允许给简单的内置类型添加方法,并且接收者的类型定义和方法声明必须在同一个包里,我们必须要使用type关键字临时定义一个新的类型。这里要注意的是,虽然我们定义出来的Integer和int的功能完全一样,但是它们属于不同的类型,不能互相赋值。
和别的语言比较起来,这样的定义的一个好处就是清晰。举个例子,比如在Java当中,同样的功能会写成不同的样子:
class Integer {
private int val;
public boolean less(Integer b) {
return this.val < b.val;
}
}
对于初学者而言,可能会觉得困惑,less函数当中的这个this究竟是哪里来的?其实这是因为Java的成员方法当中隐藏了this这个参数,这一点在Python当中要稍稍清晰一些,因为它将self参数明确地写了出来:
class Integer:
def __init__(self, val):
self.val = val
def less(self, val):
return self.val < val.val
而golang明确了结构体函数的接收者以及参数,显得更加清晰。
指针接收者
golang当中,我们也可以将函数的接收者定义成指针类型。
比如我们可以将刚才的函数写成这样:
type Point struct {
x int
y int
}
func (p *Point) Dis() float64 {
return math.Sqrt(float64(p.x*p.x + p.y*p.y))
}
指针接收者和类型接收者在使用上是一样的,我们并不需要将结构体转化成指针类型,可以直接进行调用。golang内部会自己完成这个转化:
func main() {
p := Point{3, 4}
fmt.Print(p.Dis())
}
那么这两者的区别是什么呢?我们既然可以定义成普通的结构体对象,为什么还要有一个指针对象的接收者呢?
其实很好理解, 两者的区别有些类似于C++当中的值传递和引用传递。在值传递当中,我们传递的是值的一个拷贝,我们在函数当中修改参数并不会影响函数外的结果。而引用传递则不然,传递的是参数的引用,我们在函数内部修改它的话,会影响函数外的值。
也就是说在golang当中,如果我们函数接收的是一个指针类型,我们可以在函数内部修改这个结构体的值。否则的话,传入的是一个拷贝,我们在其中修改值并不会影响它本身。我们来看个例子:
func (p *Point) Modify() {
p.x += 5
p.y -= 3
}
func main() {
p := Point{3, 4}
p.Modify()
fmt.Print(p)
}
上面这段代码当中函数的接收者是一个指针,所以我们得到的结果会是{8, 1},如果我们把指针去掉,改成普通的值接收的话,那么最后的结果仍然是{3, 4}。
总结
我们今天学的内容有些多,我们来简单梳理一下。首先,我们了解了通过type和struct关键字来定义一个结构体,结构体是golang当中面向对象的载体,golang抛弃了传统的面向对象的实现方式和特性,拥有自己的面向对象的理念。
对于结构体来说,我们可以把它当做是接受者传递给一个函数,使得我们可以以类似调用类当中方法的形式来调用一个函数。并且对于函数而言,接受者除了值以外还可以是一个指针。如果是指针的话,当我们对结构体值进行修改的时候,会影响到原值。即使我们定义的接收者类型是指针,我们在调用的时候也不必显示将它转化成结构体指针,golang当中会自动替我们完成这样的转化。
面向对象部分可以说是golang这一门语言当中最大的创新之一,也正是因为抛弃了传统的类以及继承、派生的概念,使得golang当中的面向对象语法糖相对简洁。也因此有人将golang称为升级版的C语言。虽然我们啰啰嗦嗦写了很多,但是实际谈到的内容并不多,我想理解起来也不会特别困难。
今天的文章到这里就结束了,如果喜欢本文,可以的话,请点个关注,给我一点鼓励,也方便获取更多文章。
本文使用 mdnice 排版
Golang简易入门教程——面向对象篇的更多相关文章
- Web压力测试工具 LoadRunner12.x简易入门教程--(一)回放与录制
LoadRunner12.x简易入门教程--(一)回放与录制 今天在这里分享一下LoadRunner12.x版本的入门使用方法,希望对刚接触LoadRunner的童鞋有所帮助. LoadRun ...
- Golang简单入门教程——函数进阶篇
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第八篇,我们来聊聊golang当中的函数. 我们在之前的时候已经介绍过了函数的基本用法,知道了怎么样设计或者是定义一 ...
- Pytest自动化测试-简易入门教程(02)
Pytest框架简介 Pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点:1.简单灵活,容易上手,支持参数化2.能够支持简单的单元测试和复杂的功能测试,3.还可以用来做sel ...
- Lua简易入门教程
环境:lua for windows (lfW)主页:http://luaforwindows.luaforge.net/https://code.google.com/p/luaforwindows ...
- 最新hadoop入门教程汇总篇(附详细图文步骤)
关于hadoop的分享此前一直都是零零散散的想到什么就写什么,整体写的比较乱吧.最近可能还算好的吧,毕竟花了两周的时间详细的写完的了hadoop从规划到环境安装配置等全部内容.写过程不是很难,最烦的可 ...
- Webpack简易入门教程
<!-- 其实网上关于webpack的教程已经很多了,但是本人在学习过程中发现很多教程有错误,或者写的很不全面,结果做的过程出现各种各样的问题,对新手不但不友好还会让人浪费很多不必要的时间.所以 ...
- Pytest自动化测试-简易入门教程(01)
我们今天主讲的内容,就是测试框架Pytest,讲到这个测试框架对于没有做过Web自动化的伙伴来说,会觉得这个东西是陌生的,那么到底什么是框架呢?什么又是自动化呢?自动化为什么又要用框架呢? 难道我学自 ...
- IOS开发入门教程-总结篇-写给狂热的编程爱好者们
程序发轻狂,代码阑珊,苹果开发安卓狂!--写给狂热的编程爱好者们 写在前面的话 学习iOS应用程序开发已有一段时间,最近稍微闲下来了,正好也想记录一下前阶段的整个学习过程.索性就从最基础的开始,一步一 ...
- 给萌新的Flexbox简易入门教程
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.sitepoint.com/flexbox-css-flexible-bo ...
随机推荐
- PIC单片机的for定时
看到公司的一个项目上的用的for定时 但是网上查找看到<PIC16系列单片机C程序设计与PROTEUS仿真> 上有关于for语句的定时 void Delay(unsigned int n) ...
- Thunar左侧边栏不完全显示PLACES的解决
场景 我的笔记本装上系统时用的英文,安装中文之后,发现文件管理器的默认的几个文件夹 Desktop.Music.Videos.Downloads等都变成了中文,由于是新安装的系统,就重新生成 loca ...
- 【C++】简介
注意:以下内容摘自文献[1],修改了部分内容. 前言 关于软件产业发展史,不妨访问“首次全面深度解密华为方舟编译器”一文,不仅详细介绍了软件产业的发展,还有华为方舟编译器产生的背景,值得一看! 1. ...
- 【Ubuntu】安装Ubuntu18.04.2LTS
环境:win10专业版.联想30D9主板 ubuntu:18.04.2LTS:Ubuntu镜像传送门:https://ubuntu.com/download/desktop 有两块硬盘,win10安装 ...
- 读Pyqt4教程,带你入门Pyqt4 _013
你是否曾经看着应用程序并思考特定的GUI项是如何产生的?大概每位程序员都这样过.然后你能看到你喜欢的GUI库提供的一系列窗口组件,但是你无法找到它.工具包通常仅仅提供最常用的窗口组件,比如按钮.文本组 ...
- 用pandas处理数据遇到的坑
1.使用pandas.read_csv(filePath)方法来读取csv文件时,可能会出现这种错误:ParserError:Error tokenizing data.C error:Expecte ...
- LDA模型笔记
“LDA(Latent Dirichlet Allocation)模型,模型主要解决文档处理领域的问题,比如文章主题分类.文章检测.相似度分析.文本分段和文档检索等问题.LDA主题模型是一个三层贝叶斯 ...
- 50个SQL语句(MySQL版) 问题十一
--------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 tea ...
- Redis 入门到分布式 (二)API的理解和使用
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 内容: 通用命令 单线程架构 数据结构和内部编码 一.常用的通用命令: keys 计算所有的 ...
- Java实现 LeetCode 689 三个无重叠子数组的最大和(换方向筛选)
689. 三个无重叠子数组的最大和 给定数组 nums 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为k,我们要使这3*k个项的和最大化. 返回每个区间起始索引的列表(索引从 0 ...