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 ...
随机推荐
- [JavaWeb基础] 019.Struts2 MVC架构之ModelDriven
用过struts1的人接触struts2的时候,通常会产生一个疑惑,明明struts1已经把action的form分开了,为什么struts2确把模型放在action中定义.其实这个方式只是想让act ...
- 【Python】自己写日志功能
Python有自带的logging模块,用于日志记录,功能很强大,但不好用,使用挺麻烦的,而且发现了几个bug,调用了一个logger.warning()一次,结果日志文件中出现了n行记录,且逐渐变成 ...
- 新手福利!Blazor 从入门到砖家系列教程(你真的可以成为砖家)
注意 作为 Blazor 新手的你(不是新手就当没看到这句话),请一定走完本教程再去上手其他组件库 标题跟你开个玩笑,你真的可以通过这个系列教程成为专家! 深入浅出,我翻译过程中都学到了很多. 我们不 ...
- 啪啪,打脸了!领导说:try-catch必须放在循环体外!
哈喽,亲爱的小伙伴们,技术学磊哥,进步没得说!欢迎来到新一期的性能解读系列,我是磊哥. 今天给大家带来的是关于 try-catch 应该放在循环体外,还是放在循环体内的文章,我们将从性能和业务场景分析 ...
- ie时间格式NAN-NAN-NAN
js的日期对象可以识别的日期字符串有四种: 1.YYYY-MM-DD 2019-11-11 01:01:012.MM-DD-YYYY 11-11-2019 01:01:013.YYYY/MM/DD 2 ...
- Rocket - tilelink - AtomicAutomata之二
https://mp.weixin.qq.com/s/XDUtw0uPrVXC4CChbydF_A 分析在透传和代理两种模式下,AtomicAutomata可能出现的问题. 1. 透 ...
- SpringMVC(一)概述、解析器与注解
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.SpringMVC的概述 1.概述 Spring MVC框架是一个开源的Java平台,为开发强大的基 ...
- Java实现蓝桥杯 算法训练 Professor Monotonic's Network
试题 算法训练 Professor Monotonic's Network 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 无聊的教授最近在做一项关于比较网络的实验.一个比较网络由若 ...
- Java实现 蓝桥杯VIP 算法提高 计算器
算法提高 计算器 时间限制:1.0s 内存限制:256.0MB [问题描述] 王小二的计算器上面的LED显示屏坏掉了,于是他找到了在计算器维修与应用系学习的你来为他修计算器. 屏幕上可以显示0~9的数 ...
- Java实现 蓝桥杯VIP 算法提高 项链
算法提高 项链 时间限制:1.0s 内存限制:512.0MB 问题描述 由 n(1≤n≤100) 个珠子组成的一个项链,珠子有红.蓝.白三种颜色,各种颜色的珠子的安排顺序由键盘输入的字符串任意给定.蓝 ...