其实最近看了不少Golang接口以及方法的阐述都有一个地方没说得特别明白。就是在Golang编译隐式转换传递给方法使用的时候,和调用函数时的区别。

我们都知道,在我们为一个类型变量申明了一个方法的时候,我们可以使用类似于self.method来调用这个方法,而且无论你申明的方法的接收器是指针接收器还是值接收器,Golang都可以帮你隐式转换为正确的值供方法使用。

让我们来看一个例子:

package main

import "fmt"

type duration int

func (d *duration) pretty() string {
return fmt.Sprintf("Duration: %d", d)
} func main() {
var kk duration
kk = 3
kk.pretty()
}

在这个例子中,创建了一个类型为duration的变量kk,并且duration这个类型上有指针接收器的方法pretty()这个时候无论你使用kk.pretty()还有使用(&kk).pretty()都会正确执行,并且就算接收器不是指针类型而是值类型,同上一样。Golang编译器会将你传入的值隐式转换为正确的传入对象。

这个不难理解,但是有一个跟他很像的特性,却会让这个问题变得很绕。那就是调用接口的时候出现的情况

同样我们来看一个例子:

package main

import (
"fmt"
) type notifier interface {
notify()
} type user struct {
name string
email string
} func(u *user) notify() {
fmt.Printf("Sending user email to %s<%s>\n",
u.name,
u.email)
} func sendNotification(n notifier) {
n.notify()
} func main() {
u := user{"Bill", "bill@xiachufang.com"}
sendNotification(&u)
}

这个例子就不是用类型直接调用自己的方法了,而是把自己当作参数传递给接口。让接口去执行对应方法。

这里注意,接口对于类型的要求就十分严格了,接口在神明的时候会指定,拥有哪些方法(这里的方法指 方法名, 方法参数,以及方法返回类型)。实现了这些方法就实现了这个接口。这里我们调用sendNotification这个方法需要传递进实现了notifier这个接口的变量做参数。查看notifier代码可以注意到,他实现了一个notify的方法。而我们的user实现了一个指针接收器的notify方法。但是这里注意,传递值必须遵守一个条件即:

如果接口实现方法,类型自己的实现使用的是值接收器,那么在传递值的时候无论使用指针还是值都可以。

如果接口实现方法,类型自己的实现使用的是指针接收器,那么在传递值的时候必须传递地址。

所以上面的例子,接收器是指针接收器,我们必须传递地址,如果传递值则会报错。

那么是为什么这里又不能进行隐式转换了呢?

实际上是因为,编译器并不能总能自动获得一个值的地方,也就是说你传u,编译器不一定能知道u的地址是啥。。他可能没有办法帮你完成转换。

Reference:

GO IN ACTION  William Kennedy

Golang的方法传递值应该注意的地方的更多相关文章

  1. Java面向对象-方法的值传递和引用传递

    Java面向对象-方法的值传递和引用传递 0 发布时间:『 2016-08-21 14:21』  博客类别:Java核心基础  阅读(197) 评论(0) Java面向对象-方法的值传递和引用传递 方 ...

  2. SpringMVC入门(二)—— 参数的传递、Controller方法返回值、json数据交互、异常处理、图片上传、拦截器

    一.参数的传递 1.简单的参数传递 /* @RequestParam用法:入参名字与方法名参数名不一致时使用{ * value:传入的参数名,required:是否必填,defaultValue:默认 ...

  3. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  4. GoLang之方法与接口

    GoLang之方法与接口 Go语言没有沿袭传统面向对象编程中的诸多概念,比如继承.虚函数.构造函数和析构函数.隐藏的this指针等. 方法 Go 语言中同时有函数和方法.方法就是一个包含了接受者的函数 ...

  5. Golang之方法(自定义类型,struct)

    方法的使用,请看本天师的代码 //Golang的方法定义 //Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,不仅仅是struct //定义:func (recevier ...

  6. ASP.NET页面之间传递值的几种方式

    目录 QueryString Session Cookie Application 一.QueryString QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中. ...

  7. 如何解决Response.Redirect方法传递汉字丢失或乱码问题?

    为了确保传递的汉字被正确地接收,可以在传值之前使用Server对象的UrlEncode方法对所传递的汉字进行URL编码.代码如下: String name = Server.UrlEncode(&qu ...

  8. [转]ASP.NET页面之间传递值的几种方式

    页面传值是学习asp.net初期都会面临的一个问题,总的来说有页面传值.存储对象传值.ajax.类.model.表单等.但是一般来说,常用的较简单有QueryString,Session,Cookie ...

  9. 给方法传递参数:ref参数和out参数

    /*--------------------------------------------------- 给方法传递参数:ref参数和out参数 (P106) ------------------- ...

随机推荐

  1. 文本分类实战(一)—— word2vec预训练词向量

    1 大纲概述 文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类.总共有以下系列: word2vec预训练词向量 te ...

  2. 二、Oracle 数据库基本操作

    一.oracle常用数据类型数字:number(p,s) p表示数字的长度包括小数点后的位数,s表示小数点后的位数固定长度字符:char(n):n表示最大长度,n即是最大也是固定的长度,当数据不满长度 ...

  3. Quartz动态添加定时任务执行sql(服务启动添加+手动添加)

    系统用来每天插入视图数据... 一.数据库表设计 1.接口配置表(t_m_db_interface_config) 2.接口日志表(t_m_db_interface_log) 3.前端配置页面 查询页 ...

  4. TFT1.44显示屏

    下载这个库 普通arduino的接口 链接 UTFT myGLCD(LPH9135,6,5,2,3,4); mega2560的接口连接 UTFT myGLCD(QD_TFT180A,A2,A1,A5, ...

  5. Vue+element-ui 重置组件样式的写法

    两种方式实现element-ui组件的样式 方案1:重置的公共组件样式的写法如下 然后在main.js中引入 import '@/assets/css/element.css'   方案2:每个.vu ...

  6. SQL Server 分析函数和排名函数

    分析函数基于分组,计算分组内数据的聚合值,经常会和窗口函数OVER()一起使用,使用分析函数可以很方便地计算同比和环比,获得中位数,获得分组的最大值和最小值.分析函数和聚合函数不同,不需要GROUP ...

  7. Charles 抓包工具安装和采坑记录

    Charles 抓包工具安装和采坑记录 网络抓包是解决网络问题的第一步,也是网络分析的基础.网络出现问题,第一步肯定是通过抓包工具进行路径分析,看哪一步出现异常.做网络爬虫,第一步就是通过抓包工具对目 ...

  8. Java基础之数据比较Integer、Short、int、short

    基础很重要,基础很重要,基础很重要.重要的事情说三遍,. 今天聊一聊Java的数据比较,这个范围比较大,基础类型的比较.引用类型的比较. 前提: 1.Java和c#都提供自动装箱和自动拆箱操作,何为自 ...

  9. 跨语言调用Hangfire定时作业服务

    跨语言调用Hangfire定时作业服务 背景 Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作.内置对任务的可视化操作.非常方便. 但令人遗憾的是普遍都是业务代码和hagnfire服 ...

  10. 一、Xadmin------安装

    翻译:http://xadmin.readthedocs.io/en/docs-chinese 1.安装方法: 1)pip install django-xadmin 2)通过源文件安装,我是通过这种 ...