解锁即可观看《Go开发工程师》完整课程视频

Go开发工程师

未来3-5年企业高性能项目不可替代的语言,从基础到项目实战再到重构,真正从入门到精通

【第1周】Go基础知识入门
【第2周】容器,go编程思想
【第3周】Go并发编程和工程管理
【第4周】从0开始理解rpc和grpc
【第5周】grpc和protobuf进阶
【第6周】 yapi文档管理、gorm详解
【第7周】gin快速入门
【第8周】用户服务的grpc服务
【第9周】用户服务的web服务
【第10周】服务注册/发现、配置中心、负载均衡
【第11周】商品微服务的grpc服务
【第12周】 商品微服务的gin层和oss图片服务
【第13周】库存服务和分布式锁
【第14周】订单和购物车微服务
【第15周】 支付宝支付、用户操作微服务、前后端联调
【第16周】elasticsearch实现搜索微服务
【第17周】 分布式理论基础、分布式事务解决方案
【第18周】 学习rocketmq实现幂等性机制等
【第19周】链路追踪、限流、熔断、降级
【第20周】api网关、部署
【第21周】开发规范和go基础扩展
【第22周】设计模式和单元测试
【第23周】protoc插件开发、cobra命令行
【第24周】log日志包设计
【第25周】ast代码生成工具开发
【第26周】三层代码结构
【第27周】grpc服务封装更方便的rpc服务
【第28周】深入grpc的服务注册、负载均衡原理
【第29周】基于gin封装api服务
【第30周】可观测的终极解决方案
【第31周】系统监控核心
【第32周】用户、商品服务重构
【第33周】订单、库存等服务重构
【第33+周】订单服务重构、wire进行ioc控制
【第34周】通过k8s部署服务
【第34+周】devops和k8s
章节
问答
课签
笔记
评论
占位
占位

Go语言-指针

    我们在前面多次提到过指针及指针类型。例如,*PersonPerson的指针类型。又例如,表达式&p的求值结果是p的指针。方法的接收者类型的不同会给方法的功能带来什么影响?该方法所属的类型又会因此发生哪些潜移默化的改变?现在,我们就来解答第一个问题。至于第二个问题,我会在下一小节予以解答。

    指针操作涉及到两个操作符——&*。这两个操作符均有多个用途。但是当它们作为地址操作符出现时,前者的作用是取址,而后者的作用是取值。更通俗地讲,当地址操作符&被应用到一个值上时会取出指向该值的指针值,而当地址操作符*被应用到一个指针值上时会取出该指针指向的那个值。它们可以被视为相反的操作。
  
    除此之外,当*出现在一个类型之前(如*Person*[3]string)时就不能被看做是操作符了,而应该被视为一个符号。如此组合而成的标识符所表达的含义是作为第二部分的那个类型的指针类型。我们也可以把其中的第二部分所代表的类型称为基底类型。例如,*[3]string是数组类型[3]string的指针类型,而[3]string*[3]string的基底类型。
  
    好了,我们现在回过头去再看结构体类型Person。它及其两个方法的完整声明如下:

type Person struct {
    Name    string
    Gender  string
    Age     uint8
    Address string
}

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

func (person *Person) Move(newAddress string) string {
    old := person.Address
    person.Address = newAddress
    return old
}

    注意,Person的两个方法GrowMove的接收者类型都是*Person,而不是Person。只要一个方法的接收者类型是其所属类型的指针类型而不是该类型本身,那么我就可以称该方法为一个指针方法。上面的Grow方法和Move方法都是Person类型的指针方法
  
    相对的,如果一个方法的接收者类型就是其所属的类型本身,那么我们就可以把它叫做值方法。我们只要微调一下Grow方法的接收者类型就可以把它从指针方法变为值方法:

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

    那指针方法和值方法到底有什么区别呢?我们在保留上述修改的前提下编写如下代码:

p := Person{"Robert", "Male", 33, "Beijing"}
p.Grow()
fmt.Printf("%v\n", p)   

    这段代码被执行后,标准输出会打印出什么内容呢?直觉上,34会被打印出来,但是被打印出来的却是33。这是怎么回事呢?Grow方法的功能失效了?!
  
    解答这个问题需要引出一条定论:方法的接收者标识符所代表的是该方法当前所属的那个值的一个副本,而不是该值本身。例如,在上述代码中,Person类型的Grow方法的接收者标识符person代表的是p的值的一个拷贝,而不是p的值。我们在调用Grow方法的时候,Go语言会将p的值复制一份并将其作为此次调用的当前值。正因为如此,Grow方法中的person.Age++语句的执行会使这个副本的Age字段的值变为34,而pAge字段的值却依然是33。这就是问题所在。
  
    只要我们把Grow变回指针方法就可以解决这个问题。原因是,这时的person代表的是p的值的指针的副本。指针的副本仍会指向p的值。另外,之所以选择表达式person.Age成立,是因为如果Go语言发现person是指针并且指向的那个值有Age字段,那么就会把该表达式视为(*person).Age。其实,这时的person.Age正是(*person).Age的速记法。

任务

在命令源码文件index.go中,我已经编写好了结构体类型MyInt及其两个方法。我希望在该文件被运行之后在标准输出上打印出true。但是好像哪里出了问题,致使标准输出上总是出现false。你能帮我找出问题所在并修正它吗?要求仅对一处做出修改。

?不会了怎么办

MyInt类型的Decrease方法由值方法改为指针方法即可。至于怎样改请回顾本节的“知识要点”。

||

提问题

写笔记

公开笔记
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

收藏课程后,能更快找到我哦~

使用 Ctrl+D 可将课程添加到书签

邀请您关注公众号
关注后,及时获悉本课程动态

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最热 最新
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?