Go 语言 类型方法是一种对类型行为的封装 。Go 语言的方法非常纯粹, 可以看作特殊类型的函数,其显式地将对象实例或指针作为函数的第一个参数,并且参数可以自己指定,而不强制要求一定是 this或self。 这个对象实例或指针称为方法的接收者 (reciever)。

方法声明

为命名类型定义方法的语法格式如下:

  1. // 类型方法接收者是值类型
  2. func (t TypeName) MethodName (ParamList ) (Returnlist) {
  3. // method body
  4. }
  5.  
  6. // 类型方法接收者是指针
  7. func (t *TypeName) MethodName (ParamList) (Returnlist) {
  8. // method body
  9. }

说明:

  • t 是接收者,可以自由指定名称。
  • TypeName 为命名类型的类型名。
  • MethodName 为方法名,是 个自定义标识符。
  • ParamList 是形参列表。
  • ReturnList 是返回值列表。

  Go语言的类型型方法本质上就是一个函数,没有使用隐式的指针,这是Go的优点,简单明了。我们可以将类型的方法改写成常规的函数。示例如下:

  1. // 类型方法接收者是值类型
  2. func TypName MethodName(t TypeName , otherParamList) (Returnlist) {
  3. //method body
  4. }
  5.  
  6. // 类型方法接收者是指针
  7. func TypName MethodName (t *TypeName , otherParamList) (Returnlist) {
  8. //method body
  9. }
  10.  
  11. // 示例
  12. type SliceInt []int
  13.  
  14. // 定义一个 SliceInt的方法,实现累加切边成员的功能
  15. func (s SliceInt) Sum() int {
  16. sum := 0
  17. for _, i := range s{
  18. sum += i
  19. }
  20. return sum
  21. }
  22.  
  23. // 这个函数和上面的方法等价
  24. func SliceInt_Sum(s SliceInt) int {
  25. sum := 0
  26. for _, i := range s {
  27. sum += i
  28. }
  29. return sum
  30. }
  31.  
  32. var s SliceInt = [] int {1, 2, ,3, 4}
  33. // 使用方法访问
  34. s.Sum()
  35. // 直接访问
  36. SliceInt_Sum(s)

类型方法有如下特点

  (1)可以为命名类型增加方法(除了接口),非命名类型不能自定义方法。 (非命令类型指型由预声明类型、关键字和操作符组合而成的类型,例如数组、切边、通道、指针、函数等)

比如不能为 [ ] int 类型增加方法,因为 [ ] int 是非命名类型。接口类型本身就是一个方法的签名集合,所以不能为其增加具体的实现方法。

   (2)为类型增加方法有一个限制,就是方法的定义必须和类型的定义在同一个包中。

  不能再为 int、bool 等预声明类型增加方法,因为它们是命名类型,但它们是 Go 语言内置的预声明类型,作用域是全局的,为这些类型新增的方法是在某个包中,这与第(2)条规则冲突,所以Go编译器拒绝为int增加方法。

   (3)方法的命名空间的可见性和变量一样,大写开头的方法可以在包外被访问,否则只能 在包内可见。

(4)使用 type 定义的自定义类型是一个新类型,新类型不能调用原有类型的方法,但是底层类型支持的运算可以被新类型继承。

  1. type Map map[string)string
  2.  
  3. func (m Map) Print() {
  4. // 类型支持的 range 运算 新类型可用
  5. for _, key := range m{
  6. fmt.Println(key)
  7. }
  8. }
  9.  
  10. type MyInt int
  11.  
  12. func main() {
  13. var a MyInt = 10
  14. var b MyInt = 10
  15.  
  16. // int 类型支持的加减乘除运算,新类型同样可用
  17. c := a + b
  18. d := a * b
  19.  
  20. fmt.Println("%d\n", c)
  21. fmt.Println("%d\n", d)
  22. }

方法调用  

总结一下方法调用,类型方法的一般调用方式:

  1. TypeinstanceName.MethodName(ParamList)
    1. TypeinstanceName 类型实例名或指向实例的指针变量名;
    1. MethodName 类型方法名;
    1. ParamList 方法实参。  

示例:

  1. type T struct {
  2. a int
  3. }
  4.  
  5. func (t T) Get() int {
  6. return t.a
  7. }
  8.  
  9. func (t *T) Set (i int) {
  10. t. a = i
  11. }
  12.  
  13. var t = &T{}
  14.  
  15. // 普通方法调用
  16. t.Set(2)
  17.  
  18. // 普通方法调用
  19. t.Get( )     

方法值( method value )

变量x的静态类型是T, M是类型T的一个方法, x.T被称为方法值(method value), x.T是一个函数类型变量,可以赋值给其他变量 。例如:

  1. f : = x.M
  2. f (args .. . )

等价于

  1. x.M(args ... )

方法值(method value)其实是一个带有闭包的函数变量,其底层实现原理和带有闭包的匿名函数类似,接收值被隐式地绑定到方法值(method value)的闭包环境中。后续调用不需要再显式地传递接收者。例如:

  1. type T struct {
  2. a int
  3. }
  4.  
  5. func (t T) Get() int {
  6. return t.a
  7. }
  8.  
  9. func (t *T) Set (i int ) {
  10. t.a = i
  11. }
  12.  
  13. func (t *T) Print () {
  14. fmt.Printf ("%p, %v, %d \n", t, t, t.a)
  15. }
  16.  
  17. var t =&T{}
  18.  
  19. //method value
  20. f := t.Set
  21.  
  22. // 方法值调用
  23. f(2)
  24. t.Print() //结果为 0xc4200140b8, &{2}, 2
  25.  
  26. //方法值调用, 接受值保存了方法值的环境
  27. f(3)
  28. t.Print() //结果为 0xc4200140b8, &{3}, 3

 

golang方法详解的更多相关文章

  1. session的使用方法详解

    session的使用方法详解 Session是什么呢?简单来说就是服务器给客户端的一个编号.当一台WWW服务器运行时,可能有若干个用户浏览正在运正在这台服务器上的网站.当每个用户首次与这台WWW服务器 ...

  2. Kooboo CMS - Html.FrontHtml[Helper.cs] 各个方法详解

    下面罗列了方法详解,每一个方法一篇文章. Kooboo CMS - @Html.FrontHtml().HtmlTitle() 详解 Kooboo CMS - Html.FrontHtml.Posit ...

  3. HTTP请求方法详解

    HTTP请求方法详解 请求方法:指定了客户端想对指定的资源/服务器作何种操作 下面我们介绍HTTP/1.1中可用的请求方法: [GET:获取资源]     GET方法用来请求已被URI识别的资源.指定 ...

  4. ecshop后台增加|添加商店设置选项和使用方法详解

    有时候我们想在Ecshop后台做个设置.radio.checkbox 等等来控制页面的显示,看看Ecshop的设计,用到了shop_config这个商店设置功能 Ecshop后台增加|添加商店设置选项 ...

  5. (转)Spring JdbcTemplate 方法详解

    Spring JdbcTemplate方法详解 文章来源:http://blog.csdn.net/dyllove98/article/details/7772463 JdbcTemplate主要提供 ...

  6. C++调用JAVA方法详解

    C++调用JAVA方法详解          博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...

  7. windows.open()、close()方法详解

    windows.open()方法详解:         window.open(URL,name,features,replace)用于载入指定的URL到新的或已存在的窗口中,并返回代表新窗口的Win ...

  8. CURL使用方法详解

    php采集神器CURL使用方法详解 作者:佚名  更新时间:2016-10-21   对于做过数据采集的人来说,cURL一定不会陌生.虽然在PHP中有file_get_contents函数可以获取远程 ...

  9. JAVA 注解的几大作用及使用方法详解

    JAVA 注解的几大作用及使用方法详解 (2013-01-22 15:13:04) 转载▼ 标签: java 注解 杂谈 分类: Java java 注解,从名字上看是注释,解释.但功能却不仅仅是注释 ...

随机推荐

  1. Mayor's posters POJ - 2528 线段树(离散化处理大数?)

    题意:输入t组数据,输入n代表有n块广告牌,按照顺序贴上去,输入左边和右边到达的地方,问贴完以后还有多少块广告牌可以看到(因为有的被完全覆盖了). 思路:很明显就是线段树更改区间,不过这个区间的跨度有 ...

  2. kaggle入门——泰坦尼克之灾

    目录 引言 数据认识 总结 特征处理 建模预测 logistic分类模型 随机森林 SVM xgboost 模型验证 交叉验证 学习曲线 高偏差: 高方差 模型融合 总结 后记 引言 一直久闻kagg ...

  3. Java构造器(构造方法/constructor)

    我们先来看一下什么是构造器: 1.构造器也叫构造方法或构造函数,分为有参构造器和无参构造器: 2.构造器也是一种方法,只不过是一种特殊的方法,它会在对象创建的时候被调用: 3.构造器最大的作用就是在创 ...

  4. ElasticSearch、IK分词器、Head Master安装-----Windows

    一.下载 地址:https://www.elastic.co/cn/downloads/elasticsearch 历史版本:找到下面这句话 然后双击 Not the version you're l ...

  5. G 树的难题

    时间限制 : 10000 MS   空间限制 : 165536 KB 评测说明 : 1s,128m 问题描述 给出一个无根树.树有N个点,边有权值.每个点都有颜色,是黑色.白色.灰色这三种颜色之一,称 ...

  6. JVM基础结构与字节码执行引擎

    JVM基础结构 JVM内部结构如下:栈.堆. 栈 JVM中的栈主要是指线程里面的栈,里面有方法栈.native方法栈.PC寄存器等等:每个方法栈是由栈帧组成的:每个栈帧是由局部变量表.操作数栈等组成. ...

  7. Git应用详解第二讲:Git删除、修改、撤销操作

    前言 前情提要:Git应用详解第一讲:Git分区,配置与日志 在第一讲中我们对Git进行了简单的入门介绍,相信聪明的你已经了解Git的基本使用了. 这一讲我们来进一步深入学习Git应用,着重介绍Git ...

  8. PHP的运行方式(SAPI)

    PHP 常量 PHP_SAPI 具有和 php_sapi_name() 相同的值. define('IS_CGI',(0 === strpos(PHP_SAPI,'cgi') || false !== ...

  9. SpringMVC(三):转发和重定型

    本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...

  10. 微信小程序动态修改页面标题setNavigationBarTitle

    微信小程序是可以动态修改页面标题的. 首先我们来看看静态是怎么实现的 在对应页面的json文件里面加入下面代码就可以实现了 { "navigationBarTitleText": ...