当前位置: 首页 > news >正文

【高级数据类型2】- 8. 结构体和方法

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

Go语言-结构体和方法

    Go语言的结构体类型(Struct)比函数类型更加灵活。它可以封装属性和操作。前者即是结构体类型中的字段,而后者则是结构体类型所拥有的方法。
  
    结构体类型的字面量由关键字type、类型名称、关键字struct,以及由花括号包裹的若干字段声明组成。其中,每个字段声明独占一行并由字段名称(可选)和字段类型组成。示例如下:

type Person struct {
    Name   string
    Gender string
    Age    uint8
}

    结构体类型Person中有三个字段,分别是NameGenderAge。我们可以用字面量创建出一个该类型的值,像这样:

Person{Name: "Robert", Gender: "Male", Age: 33}

    可以看到,结构体值的字面量(或简称结构体字面量)由其类型的名称和由花括号包裹的若干键值对组成。注意,这里的键值对与字典字面量中的键值对的写法相似,但不相同。这里的键是其类型中的某个字段的名称(注意,它不是字符串字面量),而对应的值则是欲赋给该字段的那个值。另外,如果这里的键值对的顺序与其类型中的字段声明完全相同的话,我们还可以统一省略掉所有字段的名称,就像这样:

Person{"Robert", "Male", 33}

    当然,我们在编写某个结构体类型的值字面量时可以只对它的部分字段赋值,甚至不对它的任何字段赋值。这时,未被显式赋值的字段的值则为其类型的零值。注意,在上述两种情况下,字段的名称是不能被省略的。
    
    与代表函数值的字面量类似,我们在编写一个结构体值的字面量时不需要先拟好其类型。这样的结构体字面量被称为匿名结构体。与匿名函数类似,我们在编写匿名结构体的时候需要先写明其类型特征(包含若干字段声明),再写出它的值初始化部分。下面,我们依照结构体类型Person创建一个匿名结构体:

p := struct {
    Name   string
    Gender string
    Age    uint8
}{"Robert", "Male", 33}

    匿名结构体最大的用处就是在内部临时创建一个结构以封装数据,而不必正式为其声明相关规则。而在涉及到对外的场景中,我强烈建议使用正式的结构体类型。
  
    我在本节开始处提到过,结构体类型可以拥有若干方法(注意,匿名结构体是不可能拥有方法的)。所谓方法,其实就是一种特殊的函数。它可以依附于某个自定义类型。方法的特殊在于它的声明包含了一个接收者声明。这里的接收者指代它所依附的那个类型。我们仍以结构体类型Person为例。下面是依附于它的一个名为Grow的方法的声明:

func (person *Person) Grow() {
    person.Age++
}

    如上所示,在关键字func和名称Grow之间的那个圆括号及其包含的内容就是接收者声明。其中的内容由两部分组成。第一部分是代表它依附的那个类型的值的标识符。第二部分是它依附的那个类型的名称。后者表明了依附关系,而前者则使得在该方法中的代码可以使用到该类型的值(也称为当前值)。代表当前值的那个标识符可被称为接收者标识符,或简称为接收者。请看下面的示例:

p := Person{"Robert", "Male", 33}
p.Grow()

    我们可以直接在Person类型的变量p之上应用调用表达式来调用它的方法Grow。注意,此时方法Grow的接收者标识符person指代的正是变量p的值。这也是“当前值”这个词的由来。在Grow方法中,我们通过使用选择表达式选择了当前值的字段Age,并使其自增。因此,在语句p.Grow()被执行之后,p所代表的那个人就又年长了一岁(pAge字段的值已变为34)。
  
    需要注意的是,在Grow方法的接收者声明中的那个类型是*Person,而不是Person。实际上,前者是后者的指针类型。这也使得person指代的是p的指针,而不是它本身。至于为什么这么做,我们在讲指针的时候在予以揭晓。
  
    说到这里,熟悉面向对象编程的同学可能已经意识到,包含若干字段和方法的结构体类型就相当于一个把属性和操作封装在一起的对象。不过要注意,与对象不同的是,结构体类型(以及任何类型)之间都不可能存在继承关系。实际上,在Go语言中并没有继承的概念。不过,我们可以通过在结构体类型的声明中添加匿名字段(或称嵌入类型)来模仿继承。具体细节可以参考《Go并发编程实战》中的说明,或者关注我的后续课程。
  
    最后,结构体类型属于值类型。它的零值并不是nil,而是其中字段的值均为相应类型的零值的值。举个例子,结构体类型Person的零值若用字面量来表示的话则为Person{}

转载于:https://my.oschina.net/u/3683692/blog/3036421

相关文章:

  • 修改server 2008远程桌面端口
  • F. Multicolored Markers(数学思维)
  • 每周一练 之 数据结构与算法(Stack)
  • 逻辑回归(个人总结)-- 于俊杰
  • 工作问题总结-----付款
  • hiero_v2.0的下载安装和使用
  • LOJ#2882. 「JOISC 2014 Day4」两个人的星座(计算几何)
  • 软件实现
  • tcp的三次握手
  • 怎样提高个人素质与修养
  • echarts、higncharts折线图或柱状图显示数据为0的点
  • iOS开发的一些奇巧淫技3
  • Spring Cloud OAuth 实现微服务内部Token传递的源码解析
  • Swift实现菜单的多选
  • 预防缓存击穿-布隆过滤器
  • 230. Kth Smallest Element in a BST
  • Angular4 模板式表单用法以及验证
  • canvas 五子棋游戏
  • Django 博客开发教程 8 - 博客文章详情页
  • echarts花样作死的坑
  • JavaScript中的对象个人分享
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • python学习笔记-类对象的信息
  • select2 取值 遍历 设置默认值
  • spring boot 整合mybatis 无法输出sql的问题
  • SQLServer插入数据
  • vue.js框架原理浅析
  • windows下如何用phpstorm同步测试服务器
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 初探 Vue 生命周期和钩子函数
  • 翻译--Thinking in React
  • - 概述 - 《设计模式(极简c++版)》
  • 来,膜拜下android roadmap,强大的执行力
  • 如何设计一个微型分布式架构?
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 新手搭建网站的主要流程
  • 译自由幺半群
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • linux 淘宝开源监控工具tsar
  • ​secrets --- 生成管理密码的安全随机数​
  • $$$$GB2312-80区位编码表$$$$
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (一)kafka实战——kafka源码编译启动
  • .NET 使用 XPath 来读写 XML 文件
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .NET上SQLite的连接
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • @DataRedisTest测试redis从未如此丝滑