方法:

在函数声明时,在其名字之前放上一个变量,即是一个方法。这个附加的参数会将该函数附 加到这种类型上,即相当于为这种类型定义了一个独占的方法。

package main

import "math"

type Point struct {
X,Y float64
} func Distance(p, q Point) float64 {
return math.Hypot(q.X - p.X, q.Y - p.Y)
} //Point 类型的方法
func(p Point) Distance(p, q Point) float64 {
return math.Hypot(q.X - p.X, q.Y - p.Y)
}

上面的代码里那个附加的参数p,叫做方法的接收器(receiver),早期的面向对象语言留下的遗 产将调用一个方法称为“向一个对象发送消息”。

在能够给任意类型定义方法这一点上,Go和很多其它的面向对象的语言不太一样。因此 在Go语言里,我们为一些简单的数值、字符串、slice、map来定义一些附加行为很方便。方 法可以被声明到任意类型,只要不是一个指针或者一个interface

基于指针对象的方法

当调用一个函数时,会对其每一个参数值进行拷贝,如果一个函数需要更新一个变量,或者 函数的其中一个参数实在太大我们希望能够避免进行这种默认的拷贝,这种情况下我们就需 要用到指针了。对应到我们这里用来更新接收器的对象的方法,当这个接受者变量本身比较 大时,我们就可以用其指针而不是对象来声明方法,如下:

func (p *Point) ScaleBy(factor float64){
p.X *= factor
p.Y *= factor
}

这个方法的名字是 (*Point).ScaleBy 。这里的括号是必须的;没有括号的话这个表达式可能 会被理解为 *(Point.ScaleBy) 。

在现实的程序里,一般会约定如果Point这个类有一个指针作为接收器的方法,那么所有Point 的方法都必须有一个指针接收器,即使是那些并不需要这个指针接收器的函数。

只有类型(Point)和指向他们的指针(*Point),才是可能会出现在接收器声明里的两种接收器。 此外,为了避免歧义,在声明方法时,如果一个类型名本身是一个指针的话,是不允许其出 现在接收器中的,比如下面这个例子:

type P *int
func(P) f() { /* */ } //compile err

想要调用指针类型方法 (*Point).ScaleBy ,只要提供一个Point类型的指针即可,像下面这样:

r := &Point{, }
r.ScaleBy()
fmt.Println(*r) // "{2, 4}"

如果接收器p是 一个Point类型的变量,并且其方法需要一个Point指针作为接收器,我们可以用下面这种简短 的写法:

p.ScaleBy()

编译器会隐式地帮我们用&p去调用ScaleBy这个方法。这种简写方法只适用于“变量”,包括 struct里的字段比如p.X,以及array和slice内的元素比如perim[0]。我们不能通过一个无法取到 地址的接收器来调用指针方法,比如临时变量的内存地址就无法获取得到:

Point{, }.ScaleBy()    // compile error: can't take address of Point literal

总结一下:

1. 不管你的method的receiver是指针类型还是非指针类型,都是可以通过指针/非指针类型 进行调用的,编译器会帮你做类型转换。 2. 在声明一个method的receiver该是指针还是非指针类型时,你需要考虑两方面的内部,第 一方面是这个对象本身是不是特别大,如果声明为非指针变量时,调用会产生一次拷 贝;第二方面是如果你用指针类型作为receiver,那么你一定要注意,这种指针类型指向 的始终是一块内存地址,就算你对其进行了拷贝。熟悉C或者C艹的人这里应该很快能明 白。

golang 方法的更多相关文章

  1. golang 方法接收者

    [定义]: golang的方法(Method)是一个带有receiver的函数Function,Receiver是一个特定的struct类型,当你将函数Function附加到该receiver, 这个 ...

  2. golang方法和接口

    一.  go方法 go方法:在函数的func和函数名间增加一个特殊的接收器类型,接收器可以是结构体类型或非结构体类型.接收器可以在方法内部访问.创建一个接收器类型为Type的methodName方法. ...

  3. Golang 方法method

    方法method Go中虽没有class,但依旧有method 通过显示说明receiver来实现与某个类型的结合 只能为同一个包中的类型定义方法 receiver可以是类型的值或者指针 不存在方法重 ...

  4. golang 方法内部定义子方法及调用

    package main import ( "fmt" "reflect" ) func out(ch chan int) { <-ch fmt.Prin ...

  5. Golang 方法接收者是值还是指针问题

    对于普通结构体作为接收者,值和指针并没有区别. (以下代码摘抄自Go In Action 中文版) type defaultMatcher struct{} // 方法声明为使用 defaultMat ...

  6. golang方法详解

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

  7. golang方法

    1.方法声明 在函数声明时,在其名字之前放上一个变量,即是一个方法.这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法. package main import &quo ...

  8. golang方法和函数的区别

  9. 从OOP的角度看Golang

    资料来源 https://github.com/luciotato/golang-notes/blob/master/OOP.md?hmsr=toutiao.io&utm_medium=tou ...

随机推荐

  1. java逆向工程-mybatis-generator

    题记:在快速开发的项目中有使用到,这样可以避免冗余工作 声明:参考于https://www.cnblogs.com/smileberry/p/4145872.html 环境:必须先安装maven环境, ...

  2. Ceph 分布式存储架构解析与工作原理

    目录 文章目录 目录 Ceph 简介 Ceph 的架构:分布式服务进程 Ceph Monitor(MON) Ceph Object Storage Device Daemon(OSD) Ceph Me ...

  3. fiddler抓取https的请求详解

    本文主要说明了自己在设置fiddler抓取https过程中所遇到的问题及解决步骤,特别是fiddler在设置证书的环节遇到的各种奇葩问题,特此分享! 声明:本文为原创文章,转载请注明来源:https: ...

  4. python 类中__init__函数的使用

    class F: def __init__(self): print('hello china') __init__ 是构造函数,初始化类,每当调用类的时候,就会自动执行这个函数 比如:执行 F() ...

  5. IDEA2019.2个人使用方案

    参考文档 https://segmentfault.com/a/1190000019813993?utm_source=tag-newest

  6. H5本地存储技术

    H5 Web存储技术 前言 web存储技术在初期的时候被定义为HTML5的一部分作为其API.后来被独立出来作为一份独立的标准. web存储标准包含localStorage对象和sessionStor ...

  7. SqlServer数据库查看被锁表以及解锁Kill杀死进程

    步骤1.查看锁表进程        2.杀死进程 --1.查询锁表进程 spid.和被锁表名称 tableName select request_session_id spid,OBJECT_NAME ...

  8. 爱伪装(AWZ)/爱立思(ALS)改机改串一键新机原理分析

    简介 爱伪装(AWZ)/爱立思(ALS)是一款iOS越狱系统上的改机工具,可以修改多种系统参数达到伪装设备型号及各种软硬件属性的目的,同时提供了防越狱检测机制,常用于iOS上的推广刷量,配合代理/VP ...

  9. 模块的概念、模块的导入方式【IMPORT 模块名、FROM 模块 IMOPRT 功能】、模块的搜索路径、链式导入&循环导入

    今日内容 1. 模块:模块的概念 2.导入的方式:import  from import 3. 环境变量:sys.path 4. 导入模块的顺序 5. 循环导入:模块间互相导入 模块 常见的四种模块: ...

  10. OpenStack组件——Glance镜像服务

    1.glance介绍 Glance是Openstack项目中负责镜像管理的模块,其功能包括虚拟机镜像的查找.注册和检索等. Glance提供Restful API可以查询虚拟机镜像的metadata及 ...