go 修改结构体方法_「GCTT 出品」Go 系列教程——26. 结构体取代类

Go语言中文网,致力于每日分享编码、开源等知识,欢迎关注我,会有意想不到的收获!

fff44bd1952e8da4b6a8ce9f425e8248.png

Go 支持面向对象吗?

Go 并不是完全面向对象的编程语言。Go 官网的 FAQ 回答了 Go 是否是面向对象语言,摘录如下。

可以说是,也可以说不是。虽然 Go 有类型和方法,支持面向对象的编程风格,但却没有类型的层次结构。Go 中的“接口”概念提供了一种不同的方法,我们认为它易于使用,也更为普遍。Go 也可以将结构体嵌套使用,这与子类化(Subclassing)类似,但并不完全相同。此外,Go 提供的特性比 C++ 或 Java 更为通用:子类可以由任何类型的数据来定义,甚至是内建类型(如简单的“未装箱的”整型)。这在结构体(类)中没有受到限制。

在接下来的教程里,我们会讨论如何使用 Go 来实现面向对象编程概念。与其它面向对象语言(如 Java)相比,Go 有很多完全不同的特性。

使用结构体,而非类

Go 不支持类,而是提供了结构体。结构体中可以添加方法。这样可以将数据和操作数据的方法绑定在一起,实现与类相似的效果。

为了加深理解,我们来编写一个示例吧。

在示例中,我们创建一个自定义,它帮助我们更好地理解,结构体是如何有效地取代类的。

在你的 Go 工作区创建一个名为 oop 的文件夹。在 opp 中再创建子文件夹 employee。在 employee 内,创建一个名为 employee.go 的文件。

文件夹结构会是这样:

workspacepath -> oop -> employee -> employee.go

请将 employee.go 里的内容替换为如下所示的代码。

6b0251f217732bd14f44d49fa515e50a.png

在上述程序里,第 1 行指定了该文件属于 employee 包。而第 7 行声明了一个 Employee 结构体。在第 14 行,结构体 Employee 添加了一个名为 LeavesRemaining 的方法。该方法会计算和显示员工的剩余休假数。于是现在我们有了一个结构体,并绑定了结构体的方法,这与类很相似。

接着在 oop 文件夹里创建一个文件,命名为 main.go。

现在目录结构如下所示:

10968d2b6acd7d1a450428af24dad9ad.png

main.go 的内容如下所示:

3e716a1440c7938238c398b130a9d8bb.png

我们在第 3 行引用了 employee 包。在 main()(第 12 行),我们调用了 Employee 的 LeavesRemaining() 方法。

由于有自定义包,这个程序不能在 go playground 上运行。你可以在你的本地运行,在 workspacepath/bin/oop 下输入命令 go install opp,程序会打印输出:

Sam Adolf has 10 leaves remaining

使用 New() 函数,而非构造器

我们上面写的程序看起来没什么问题,但还是有一些细节问题需要注意。我们看看当定义一个零值的 employee 结构体变量时,会发生什么。将 main.go 的内容修改为如下代码:

d08fe33df645ec7bf0b407032d98ce80.png

我们的修改只是创建一个零值的 Employee 结构体变量(第 6 行)。该程序会输出:

has 0 leaves remaining

你可以看到,使用 Employee 创建的零值变量没有什么用。它没有合法的姓名,也没有合理的休假细节。

在像 Java 这样的 OOP 语言中,是使用构造器来解决这种问题的。一个合法的对象必须使用参数化的构造器来创建。

Go 并不支持构造器。如果某类型的零值不可用,需要程序员来隐藏该类型,避免从其他包直接访问。程序员应该提供一种名为 NewT(parameters) 的 函数,按照要求来初始化 T 类型的变量。按照 Go 的惯例,应该把创建 T 类型变量的函数命名为 NewT(parameters)。这就类似于构造器了。如果一个包只含有一种类型,按照 Go 的惯例,应该把函数命名为 New(parameters), 而不是 NewT(parameters)。

让我修改一下原先的代码,使得每当创建 employee 的时候,它都是可用的。

首先应该让 Employee 结构体不可引用,然后创建一个 New 函数,用于创建 Employee 结构体变量。在 employee.go 中输入下面代码:

9b1dcc8555fedd0e325eae00e8dba919.png

我们进行了一些重要的修改。我们把 Employee 结构体的首字母改为小写 e,也就是将 type Employee struct 改为了 type employee struct。通过这种方法,我们把 employee 结构体变为了不可引用的,防止其他包对它的访问。除非有特殊需求,否则也要隐藏所有不可引用的结构体的所有字段,这是 Go 的最佳实践。由于我们不会在外部包需要 employee 的字段,因此我们也让这些字段无法引用。

同样,我们还修改了 LeavesRemaining() 的方法。

现在由于 employee 不可引用,因此不能在其他包内直接创建 Employee 类型的变量。于是我们在第 14 行提供了一个可引用的 New 函数,该函数接收必要的参数,返回一个新创建的 employee 结构体变量。

这个程序还需要一些必要的修改,但现在先运行这个程序,理解一下当前的修改。如果运行当前程序,编译器会报错,如下所示:

go/src/constructor/main.go:6: undefined: employee.Employee

这是因为我们将 Employee 设置为不可引用,因此编译器会报错,提示该类型没有在 main.go 中定义。很完美,正如我们期望的一样,其他包现在不能轻易创建零值的 employee 变量了。我们成功地避免了创建不可用的 employee 结构体变量。现在创建 employee 变量的唯一方法就是使用 New 函数。

如下所示,修改 main.go 里的内容。

adc4d39dd430999dcbb61d93c8e77233.png

该文件唯一的修改就是第 6 行。通过向 New 函数传入所需变量,我们创建了一个新的 employee 结构体变量。

下面是修改后的两个文件的内容。

260b9d96779910a1357df14070a9509d.png

main.go

ce5db956274356bcfcdb82db8d6d2808.png

运行该程序,会输出:

Sam Adolf has 10 leaves remaining

现在你能明白了,虽然 Go 不支持类,但结构体能够很好地取代类,而以 New(parameters) 签名的方法可以替代构造器。

关于 Go 中的类和构造器到此结束。祝你愉快。

上一教程 - 「GCTT 出品」Go 系列教程——25. Mutex

下一教程 - 组合取代继承


历史文章:

「GCTT 出品」Go 系列教程——1. 介绍与安装

「GCTT 出品」Go 系列教程——2. Hello World

「GCTT 出品」Go 系列教程——3. 变量

「GCTT 出品」Go 系列教程——4. 类型

「GCTT 出品」Go 系列教程——5. 常量

「GCTT 出品」Go 系列教程——6. 函数(Function)

「GCTT 出品」Go 系列教程——7. 包

Go 系列教程——8. if-else 语句

「GCTT 出品」Go 系列教程——9. 循环

「GCTT 出品」Go 系列教程——10. switch 语句

「GCTT 出品」Go 系列教程——11. 数组和切片

「GCTT 出品」Go 系列教程——12. 可变参数函数

「GCTT 出品」Go 系列教程——13. Maps

「GCTT 出品」Go 系列教程——14. 字符串

「GCTT 出品」Go 系列教程——15. 指针

「GCTT 出品」Go 系列教程——16. 结构体,这一篇就够

「GCTT 出品」Go 系列教程——17. 超全的方法教程

「GCTT 出品」Go 系列教程——18. 接口(一)

「GCTT 出品」Go 系列教程——19. 接口(二)

「GCTT 出品」Go 系列教程——20. 并发入门

「GCTT 出品」Go 系列教程——21. Go 协程

「GCTT 出品」Go 系列教程——22. 信道(channel)

「GCTT 出品」Go 系列教程——23. 缓冲信道和工作池

「GCTT 出品」Go 系列教程——24. Select

「GCTT 出品」Go 系列教程——25. Mutex

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WindowsLinux常用命令笔记

目录linux windows Linux: 1.查找文件 find / -name filename.txt 根据名称查找/目录下的filename.txt文件。 find . -name "*.xml" 递归查找所有的xml文件 find . -name "*.xml" |xargs grep "hello world" 递归查找所有文件内容中包含hello w…

button 和input 的区别及在表单form中的用法

先说一下button 和input的定义&#xff1a; <button> 标签定义的是一个按钮 1、在 <button> 元素内部&#xff0c;您可以放置任何内容&#xff0c;比如文本或图像。这是该元素与使用 <input> 元素创建的按钮之间的不同之处&#xff1b; 2、 <button> …

走向REST:在Spring和JAX-RS(Apache CXF)中嵌入Jetty

对于服务器核心Java开发人员而言&#xff0c;向世界“展示”的唯一方法是使用API​​。 今天的帖子都是关于JAX-RS的 &#xff1a;使用Java编写和公开RESTful服务。 但是&#xff0c;我们不会使用涉及应用程序服务器&#xff0c;WAR打包以及诸如此类的传统的重量级方法来做到这…

分组后分页_SQL(约束、视图、分页、序列、索引、同义词、创建用户,为用户授权、执行计划的使用 数据的导入导出)...

学习主题&#xff1a;SQL学习目标&#xff1a;掌握约束掌握视图修改表名与删除表删除表中的列语句的语法结构是什么&#xff1f;答&#xff1a;delete 表名from table where ;删除表中的列语句的语法结构是什么&#xff1f;答&#xff1a;delete 表名from table where ;截断表的…

第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息...

第三百三十四节&#xff0c;web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻&#xff0c;爬取Ajax动态生成的信息 crapy爬取百度新闻&#xff0c;爬取Ajax动态生成的信息&#xff0c;抓取百度新闻首页的新闻rul地址 有多网站&#xff0c;当你浏览器访问时看到的信息&#xf…

BEM思想之彻底弄清BEM语法

BEM的意思就是块&#xff08;block&#xff09;、元素&#xff08;element&#xff09;、修饰符&#xff08;modifier&#xff09;,是由Yandex团队提出的一种前端命名方法论。这种巧妙的命名方法让你的CSS类对其他开发者来说更加透明而且更有意义。BEM命名约定更加严格&#xf…

Hibernate Search 4.2最终发布:支持空间查询

JBoss已宣布发布Hibernate Search 4.2 final。 您可以从Sourceforge下载它或使用Maven构件 。 在新版本中&#xff0c;包含了一些有趣的功能&#xff1a; Hibernate Search现在支持空间查询 。 使用Spatial扩展&#xff0c;您可以将全文查询与基于到空间点的距离的限制结合起…

推荐算法

5类系统推荐算法,非常好使,非常全 今日头条用了哪五种推荐算法 视频 今日头条核心技术“个性推荐算法”揭秘转载于:https://www.cnblogs.com/lhuser/p/8306092.html

python的应用包括哪些_Python应用领域有哪些?

1、数据分析与处理通常情况下&#xff0c;Python被用来做数据分析。用C设计一些底层的算法进行封装&#xff0c;然后用Python进行调用。因为算法模块较为固定&#xff0c;所以用Python直接进行调用&#xff0c;方便且灵活&#xff0c;可以根据数据分析与统计的需要灵活使用。Py…

win10系统同时安装python2和python3

1、官网下载python2和python3版本 2、安装python3&#xff0c;勾上Add Python3.5 to PATH&#xff0c;自定义选择安装目录&#xff0c;安装&#xff0c;验证&#xff1a;WINR--->cmd&#xff0c;输入python看看是否安装python3 3、安装python2&#xff0c;自定义安装目录&am…

使用NoSQLUnit测试Spring Data MongoDB应用程序

Spring Data MongoDB是Spring Data项目中的项目&#xff0c;它提供了Spring编程模型的扩展&#xff0c;用于编写使用MongoDB作为数据库的应用程序。 要使用NoSQLUnit为Spring Data MongoDB应用程序编写测试&#xff0c;除了考虑Spring Data MongoDB使用一个名为_class的特殊属…

20170117小测

今天再次迎来了我们的例行考试。 T1&#xff1a; 首先我们考虑那些点是可以共存的&#xff0c;我们可以枚举一个质数做他们的gcd&#xff0c;然后把这些点放在一张图里求直径。所以我们要做的就是把这些点的值分解质因数&#xff0c;对每个质因数挂一个链&#xff0c;代表有那些…

java实现红包要多少钱_java实现红包的分配算法

个人推测&#xff0c;微信红包在发出的时候已经分配好金额。比如一个10元的红包发给甲乙丙三个人&#xff0c;其实在红包发出去的时候&#xff0c;已经确定了第一个会领取多少&#xff0c;第二个会领取多少金额。而不是在领取的时候才计算的。下面贴出实现方法&#xff1a;publ…

iOS中Safari浏览器select下拉列表文字太长被截断的处理方法

网页中的select下拉列表&#xff0c;文字太长的话在iOS的Safari浏览器里会被自动截断&#xff0c;显示成下面这种&#xff1a; 安卓版的浏览器则没有这个问题。 如何让下拉列表中的文字在iOS的Safari浏览器里显示完整呢&#xff1f;答案是使用<optgroup></optgroup>…

HDU1042 N!(大整数类应用)

Problem Description Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!InputOne N in one line, process to the end of file.OutputFor each N, output N! in one line.Sample Input123Sample Output126Code&#xff1a;#include <iostream> #includ…

Java内部具有原子更新的动态热交换环境

有人可能会说上述标题可以简称为OSGi &#xff0c;我想在一开始就放弃这种思考过程。 对于OSGi而言&#xff0c;这不是一个冒犯&#xff0c;这是一个很棒的规范&#xff0c;在实现层或可用性层上都弄得一团糟&#xff0c;这就是我对OSGi的信念。 当然&#xff0c;您可以使用OS…

Css Secret 案例Demo全套

Css Secret 案例全套 github地址 案例地址 去年买了一本CSS揭秘的css专题书&#xff0c;该书揭示了 47 个鲜为人知的 CSS 技巧&#xff0c;主要内容包括背景与边框、形状、 视觉效果、字体排印、用户体验、结构与布局、过渡与动画等。去年买入时&#xff0c;就决定将里面所有…

底量超顶量超级大黑马指标源码_底量超顶量+地量买点_月线底量超顶量大牛股,底量超顶量超级大黑马,底量超顶量买入指标,后量超前量买入指标_指标公式分享交流论坛_理想论坛 - 股票论坛...

l 图形特征&#xff1a;(1) 当股价从头部滑落一段时间后&#xff0c;会有一个见底回升的过程。(2) 这个头部区间的成交量称为顶量&#xff0c;见底回升时的成交量称为底量。(3) 如果底量能大大地超过顶量&#xff0c;则较容易通过顶量造成的压力带。…

php var_export与var_dump 输出的不同

问题发现在跟踪yratings_get_targets的时候&#xff0c;error_log(var_export(yblog_mspconfiginit("ratings"),true));老是打印出yblog_mspconfiginit(“ratings”)的返回是NULL 导致我以为是无法建立和DB的连接&#xff0c;走错路了一天。最后才发现&#xff0c;这…

Servlet 开发

1. Servlet &#xff08;很久远的东西&#xff0c;但是现在学习原理&#xff09; html css js 前端页面&#xff08;静态的&#xff09; form action ".html" Servlet 允许将action属性设置为映射&#xff0c;通过映射找到相关的Servlet class 进行数据的处理。…