1 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self SortableStrings) Len() int {
return len(self)
} func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func main() {
_, ok1 := interface{}(SortableStrings{}).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(SortableStrings{}).(Sortable)
fmt.Println("ok2", ok2)
}

自定义类型SortableStrings实现了接口sort.Interface中3个开放函数。自定义接口Sortable,除了包含sort.Interface的3个函数外,增加的Sort没有被SortableStrings实现。所以SortableStrings只实现了一个接口,即sort.Interface


 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self SortableStrings) Len() int {
return len(self)
} func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func (self SortableStrings) Sort() {
sort.Sort(self)
} func main() {
_, ok1 := interface{}(SortableStrings{}).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(SortableStrings{}).(Sortable)
fmt.Println("ok2", ok2)
}

对自定义类型SortableStrings增加方法Sort,其实现是调用sort.Sort函数,该函数接受一个类型为sort.Interface的参数值,并利用这个值的Len,Less,Swap方法进行排序。


 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self SortableStrings) Len() int {
return len(self)
} func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func (self *SortableStrings) Sort() {
sort.Sort(self)
} func main() {
_, ok1 := interface{}(SortableStrings{}).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(SortableStrings{}).(Sortable)
fmt.Println("ok2", ok2)
}

接口Sortable中有4个函数需要实现,虽然SortableStrings实现了4个函数,但是Sort版的实现,接收器是指针类型。SortableStrings{}是值类型,不能访问基本类型SortableStrings接收器是指针的方法(即Sort),相当于SortableStrings{}只实现了Len、Less、Swap 3个函数,少实现一个函数,所以不是Sortable类型


 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self SortableStrings) Len() int {
return len(self)
} func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func (self *SortableStrings) Sort() {
sort.Sort(self)
} func main() {
_, ok1 := interface{}(SortableStrings{}).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(&SortableStrings{}).(Sortable)
fmt.Println("ok2", ok2)
}

&SortableStrings{}是SortableStrings{}的指针类型,可以访问到基本类型SortableStrings中的4个函数。所以是Sortable的一个实现


 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self SortableStrings) Len() int {
return len(self)
} func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func (self *SortableStrings) Sort() {
sort.Sort(self)
} func main() {
_, ok1 := interface{}(&SortableStrings{}).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(&SortableStrings{}).(Sortable)
fmt.Println("ok2", ok2)
}

&SortableStrings{}是SortableStrings{}的指针类型。指针类型可以访问基本类型中接收器为值(或者指针)的类型。


 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self SortableStrings) Len() int {
return len(self)
} func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func (self *SortableStrings) Sort() {
sort.Sort(self)
} func main() {
ss := SortableStrings{"", "", ""}
ss.Sort()
fmt.Println("Sortable Strings", ss)
_, ok1 := interface{}(SortableStrings{}).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(SortableStrings{}).(Sortable)
fmt.Println("ok2", ok2) _, ok3 := interface{}(&SortableStrings{}).(sort.Interface)
fmt.Println("ok3", ok3) _, ok4 := interface{}(&SortableStrings{}).(Sortable)
fmt.Println("ok4", ok4)
}


 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self *SortableStrings) Len() int {
return len(self)
} func (self *SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self *SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func (self *SortableStrings) Sort() {
sort.Sort(self)
} func main() {
ss := SortableStrings{"", "", ""}
ss.Sort()
fmt.Println("Sortable Strings", ss)
_, ok1 := interface{}(SortableStrings{}).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(SortableStrings{}).(Sortable)
fmt.Println("ok2", ok2) _, ok3 := interface{}(&SortableStrings{}).(sort.Interface)
fmt.Println("ok3", ok3) _, ok4 := interface{}(&SortableStrings{}).(Sortable)
fmt.Println("ok4", ok4)
}


上面关于“XX可以访问OO”的描述中,“访问“一词用的不准确。值变量可以访问接收器是指针类型的方法,指针变量也可以访问接收器是值类型的方法

 package main

 import (
"fmt"
"sort"
) type SortableStrings []string type Sortable interface {
sort.Interface
Sort()
} func (self SortableStrings) Len() int {
return len(self)
} func (self SortableStrings) Less(i, j int) bool {
return self[i] < self[j]
} func (self SortableStrings) Swap(i, j int) {
self[i], self[j] = self[j], self[i]
} func (self *SortableStrings) Sort() {
sort.Sort(self)
} func main() {
ss := SortableStrings{"", "", ""}
ss.Sort() //值变量可以访问接收器是值类型的方法
fmt.Println("Sortable Strings", ss) fmt.Println("ss : self[0] < self[1]", ss.Less(, ))
fmt.Println("&ss : self[0] < self[1]", (&ss).Less(, )) //指针变量可以访问接收器是值类型的方法 _, ok1 := interface{}(ss).(sort.Interface)
fmt.Println("ok1", ok1) _, ok2 := interface{}(ss).(Sortable)
fmt.Println("ok2", ok2) _, ok3 := interface{}(&ss).(sort.Interface)
fmt.Println("ok3", ok3) _, ok4 := interface{}(&ss).(Sortable)
fmt.Println("ok4", ok4) _, ok5 := interface{}(SortableStrings{}).(sort.Interface)
fmt.Println("ok5", ok5) _, ok6 := interface{}(SortableStrings{}).(Sortable)
fmt.Println("ok6", ok6) _, ok7 := interface{}(&SortableStrings{}).(sort.Interface)
fmt.Println("ok7", ok7) _, ok8 := interface{}(&SortableStrings{}).(Sortable)
fmt.Println("ok8", ok8)
}

所以上面”访问“一词用的不准确。值变量可以访问接收器是值类型的方法  还是  指针变量可以访问接收器是值类型的方法,都是编译器帮我们做了部分转换工作。

http://play.golang.org/p/KG8-Qb7gqM

 package main

 import (
"log"
) type User struct {
Name string
Email string
} func (u *User) Notify() error {
log.Printf("User: Sending User Email To %s<%s>\n",
u.Name,
u.Email) return nil
} type Notifier interface {
Notify() error
} func SendNotification(notify Notifier) error {
return notify.Notify()
} func main() {
user := User{
Name: "AriesDevil",
Email: "ariesdevil@xxoo.com",
} SendNotification(user)
}

“值类型(或 指针类型)是否是该接口类型的实现呢?”

User的值类型变量不是 接口 Notifer的实现。也就是

 _, ok1 := interface{}(user).(Notifier)
fmt.Println("ok1", ok1) //false _, ok2 := interface{}(&user).(Notifier)
fmt.Println("ok2", ok2) //true
SendNotification(user)

上文报错,是因为user不是Notifier的实现,也就不能赋值给 SendNotification(notify Notifier)的notify.调用函数,参数就涉及到传值,只有相同类型或者其实现才可能相互赋值。如果不是调用函数,某一类型的值或者指针直接调用自己的方法(接收器是值或者指针)都是可以的

 package main

 import (
"fmt"
"log"
) type User struct {
Name string
Email string
} func (u *User) Notify() error {
log.Printf("User: Sending User Email To %s<%s>\n",
u.Name,
u.Email) return nil
} func (u User) NameString() {
u.Name = "Bob"
fmt.Println("Name", u.Name)
} func (u *User) EmailString() {
u.Email = "Bob@hotmail.com"
fmt.Println("Email", u.Email)
} type Notifier interface {
Notify() error
NameString()
EmailString()
} func SendNotification(notify Notifier) error {
return notify.Notify()
} func main() {
user := User{
Name: "AriesDevil",
Email: "ariesdevil@xxoo.com",
} user.NameString()
user.EmailString()
fmt.Println("Name", user.Name)
fmt.Println("Email", user.Email) (&user).NameString()
(&user).EmailString()
fmt.Println("Name", (&user).Name)
fmt.Println("Email", (&user).Email) _, ok1 := interface{}(user).(Notifier)
fmt.Println("ok1", ok1) //false _, ok2 := interface{}(&user).(Notifier)
fmt.Println("ok2", ok2) //true //SendNotification(user) }

Go语言——值方法 & 指针方法的更多相关文章

  1. Go语言值,指针,引用类型

    原文:https://www.jianshu.com/p/af42cb368cef ---------------------------------------------------- Go语言的 ...

  2. python 调用dll中c或c++语言的带指针方法,

    在项目开发中遇到了,python需要去调用一个动态链接库dll中的c++方法.这个方法的参数为一个指针类型的参数,一个bool类型参数, 在python中并未对数字类型进行区分. int LP_Agc ...

  3. C语言函数返回指针方法

    1.将函数内部定义的变量用static修饰 由于static修饰的变量,分配在静态内存区(类似于全局变量区),函数返回时,并不会释放内存,因此可以将要返回的变量加static修饰. int *test ...

  4. 表达式求值(二叉树方法/C++语言描述)(二)

    表达式二叉树节点的数据可能是运算数或运算符,可以使用一个联合体进行存储:同时还需要一个变量来指示存储的是运算数还是运算符,可以采用和栈方法求值中一样的枚举类型TokenType: typedef en ...

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

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

  6. 用c语言产生随机数的方法

    用c语言产生随机数的方法 在C语言中,rand()函数可以用来产生随机数,但是这不是真正意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列 ...

  7. C语言程序设计:现代方法阅读笔记

    第二十六章 atexit函数允许用户“注册”在程序终止时要调用的函数:atexit(func); 在程序终止后,func函数会被自动调用 clock()函数可以计算程序运行时间 time函数返回当前的 ...

  8. C++ 全面刨析使用指针方法 _new _delete

    指针 #include<iostream> using namespace std; int main() { ; int* pn;//声明 int* pn = &avr;//初始 ...

  9. Go 语言 结构体和方法

    @ 目录 1. 结构体别名定义 2. 工厂模式 3. Tag 原信息 4. 匿名字段 5. 方法 1. 结构体别名定义 变量别名定义 package main import "fmt&quo ...

随机推荐

  1. Spring Boot使用监听器Listener

    之前介绍了在Spring Boot中使用过滤器:https://www.cnblogs.com/zifeiy/p/9911056.html 接下来介绍使用监听器Listener. 下面是一个例子: p ...

  2. LODOP获取打印状态码和时间列表

    之前有博文介绍获取打印状态码和打印状态码的含义,相关博文:LODOP获取打印机状态码和状态码含义测试.此外 ,也有获取状态码及其变化的方法,可以获取打印状态码的列表,列表包含每个状态和每个状态的时间. ...

  3. node更改默认npm阿里地址

    npm config set registry https://registry.npm.taobao.orgsudo npm install cnpm -g --registry=https://r ...

  4. 从源码角度解析Netty的React模式是如何工作的

    Netty 支持多种实现方式,比如nio,epoll 等,本文以nio的实现方式进行讲解. 1.EventLoop : 事件循环看,简单来说就是一个死循环监听事件,如果事件来了,处理掉.通常做法就是开 ...

  5. MVC模式实现注册登录

    很多人对MVC模式搞不懂,刚开始是我也犯迷糊,知道看到一个前辈写的代码,我顿时有的恍然大悟,拿来分享给各位 MVC: 就是M:模型.V:视图(前台界面)C:后台处理的servlet 话不多说.上代码 ...

  6. 《C语言程序设计》学习笔记(二)

    第八章 函数 函数的基本概念 定义:函数由函数名.参数和函数体组成. 函数定义的一般形式: 类型说明符 函数名(形式参数声明) { [说明与定义部分] 语句: } 说明: 1.类型说明符用来说明函数的 ...

  7. Netty学习笔记(三)——netty源码剖析

    1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...

  8. TCP 客户端编程

    1.Qt中TCP客户端编程 对Qt编程而言,网络只是数据传输的通道: Qt提供了QTcpSocket类(封装了TCP协议细节): 将QTcpSocket的对象当做黑盒使用,进行数据首发. 1.1QTc ...

  9. CentOS7.5下安装nginx --项目部署

    1.安装ngnix一些依赖包 [root@VM_39_157_centos ~]# yum -y install gcc gcc-c++ openssl-devel pcre-devel httpd- ...

  10. [转帖]关于DDR4内存颗粒、单双面、主板布线和双通道的那些事儿

    我们200期的期中测试大家都做了吧,今天我们放出了完整的答案,想知道自己错在哪儿的同学赶紧过去看哟=><这次期中考试你拿到满分了吗?没有就快去补习吧> https://www.exp ...