本文始发于个人公众号: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简易入门教程——面向对象篇的更多相关文章

  1. Web压力测试工具 LoadRunner12.x简易入门教程--(一)回放与录制

        LoadRunner12.x简易入门教程--(一)回放与录制 今天在这里分享一下LoadRunner12.x版本的入门使用方法,希望对刚接触LoadRunner的童鞋有所帮助. LoadRun ...

  2. Golang简单入门教程——函数进阶篇

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第八篇,我们来聊聊golang当中的函数. 我们在之前的时候已经介绍过了函数的基本用法,知道了怎么样设计或者是定义一 ...

  3. Pytest自动化测试-简易入门教程(02)

    Pytest框架简介 Pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点:1.简单灵活,容易上手,支持参数化2.能够支持简单的单元测试和复杂的功能测试,3.还可以用来做sel ...

  4. Lua简易入门教程

    环境:lua for windows (lfW)主页:http://luaforwindows.luaforge.net/https://code.google.com/p/luaforwindows ...

  5. 最新hadoop入门教程汇总篇(附详细图文步骤)

    关于hadoop的分享此前一直都是零零散散的想到什么就写什么,整体写的比较乱吧.最近可能还算好的吧,毕竟花了两周的时间详细的写完的了hadoop从规划到环境安装配置等全部内容.写过程不是很难,最烦的可 ...

  6. Webpack简易入门教程

    <!-- 其实网上关于webpack的教程已经很多了,但是本人在学习过程中发现很多教程有错误,或者写的很不全面,结果做的过程出现各种各样的问题,对新手不但不友好还会让人浪费很多不必要的时间.所以 ...

  7. Pytest自动化测试-简易入门教程(01)

    我们今天主讲的内容,就是测试框架Pytest,讲到这个测试框架对于没有做过Web自动化的伙伴来说,会觉得这个东西是陌生的,那么到底什么是框架呢?什么又是自动化呢?自动化为什么又要用框架呢? 难道我学自 ...

  8. IOS开发入门教程-总结篇-写给狂热的编程爱好者们

    程序发轻狂,代码阑珊,苹果开发安卓狂!--写给狂热的编程爱好者们 写在前面的话 学习iOS应用程序开发已有一段时间,最近稍微闲下来了,正好也想记录一下前阶段的整个学习过程.索性就从最基础的开始,一步一 ...

  9. 给萌新的Flexbox简易入门教程

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.sitepoint.com/flexbox-css-flexible-bo ...

随机推荐

  1. [Unity2d系列教程] 005.Unity如何使用外部触控插件FingerGuesture

    用过Unity的都知道自带的Input.touches并不支持鼠标输入,给我们的调试带来很大的不方便.那么我们会发现其实有很多触控方面的插件,如inputtouches,easy touch,fing ...

  2. PowerPC-MPC56xx Flash模式启动过程

    https://mp.weixin.qq.com/s/SpBOfzJJ1OizYP-rsLJVqQ   Flash启动模式为最常用模式. 一般情况下,芯片上电之后,从flash起始位置读取第一条指令的 ...

  3. eclipse 界面复原

    Windows-----Perspective-----Reset perspective

  4. Java实现 LeetCode 704 二分查找(二分法)

    704. 二分查找 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1. 示例 1 ...

  5. Java实现 LeetCode 648 单词替换(字典树)

    648. 单词替换 在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词(successor).例如,词根an,跟随着单词 other( ...

  6. Java实现 蓝桥杯 算法提高 复数四则运算

    算法提高 6-17复数四则运算 时间限制:1.0s 内存限制:512.0MB 提交此题 设计复数库,实现基本的复数加减乘除运算. 输入时只需分别键入实部和虚部,以空格分割,两个复数之间用运算符分隔:输 ...

  7. Java实现 LeetCode 350 两个数组的交集 II(二)

    350. 两个数组的交集 II 给定两个数组,编写一个函数来计算它们的交集. 示例 1: 输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2,2] 示例 2: 输入 ...

  8. Java实现 蓝桥杯VIP 算法训练 麦森数

    算法训练 麦森数 时间限制:1.0s 内存限制:256.0MB 问题描述 形如2P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2P-1不一定也是素数.到1998年底, ...

  9. java实现 猜数字游戏

    猜数字游戏 猜数字 很多人都玩过这个游戏:甲在心中想好一个数字,乙来猜.每猜一个数字,甲必须告诉他是猜大了,猜小了,还是刚好猜中了.下列的代码模拟了这个过程.其中用户充当甲的角色,计算机充当乙的角色. ...

  10. Java实现第十届蓝桥杯质数

    试题 D: 质数 本题总分:10 分 [问题描述] 我们知道第一个质数是 2.第二个质数是 3.第三个质数是 5--请你计算 第 2019 个质数是多少? [答案提交] 这是一道结果填空的题,你只需要 ...