1.  
  2. 1 package main
  3.  
  4. import (
  5. "fmt"
  6. "sort"
  7. )
  8.  
  9. type SortableStrings []string
  10.  
  11. type Sortable interface {
  12. sort.Interface
  13. Sort()
  14. }
  15.  
  16. func (self SortableStrings) Len() int {
  17. return len(self)
  18. }
  19.  
  20. func (self SortableStrings) Less(i, j int) bool {
  21. return self[i] < self[j]
  22. }
  23.  
  24. func (self SortableStrings) Swap(i, j int) {
  25. self[i], self[j] = self[j], self[i]
  26. }
  27.  
  28. func main() {
  29. _, ok1 := interface{}(SortableStrings{}).(sort.Interface)
  30. fmt.Println("ok1", ok1)
  31.  
  32. _, ok2 := interface{}(SortableStrings{}).(Sortable)
  33. fmt.Println("ok2", ok2)
  34. }

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


  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. type SortableStrings []string
  9.  
  10. type Sortable interface {
  11. sort.Interface
  12. Sort()
  13. }
  14.  
  15. func (self SortableStrings) Len() int {
  16. return len(self)
  17. }
  18.  
  19. func (self SortableStrings) Less(i, j int) bool {
  20. return self[i] < self[j]
  21. }
  22.  
  23. func (self SortableStrings) Swap(i, j int) {
  24. self[i], self[j] = self[j], self[i]
  25. }
  26.  
  27. func (self SortableStrings) Sort() {
  28. sort.Sort(self)
  29. }
  30.  
  31. func main() {
  32. _, ok1 := interface{}(SortableStrings{}).(sort.Interface)
  33. fmt.Println("ok1", ok1)
  34.  
  35. _, ok2 := interface{}(SortableStrings{}).(Sortable)
  36. fmt.Println("ok2", ok2)
  37. }

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


  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. type SortableStrings []string
  9.  
  10. type Sortable interface {
  11. sort.Interface
  12. Sort()
  13. }
  14.  
  15. func (self SortableStrings) Len() int {
  16. return len(self)
  17. }
  18.  
  19. func (self SortableStrings) Less(i, j int) bool {
  20. return self[i] < self[j]
  21. }
  22.  
  23. func (self SortableStrings) Swap(i, j int) {
  24. self[i], self[j] = self[j], self[i]
  25. }
  26.  
  27. func (self *SortableStrings) Sort() {
  28. sort.Sort(self)
  29. }
  30.  
  31. func main() {
  32. _, ok1 := interface{}(SortableStrings{}).(sort.Interface)
  33. fmt.Println("ok1", ok1)
  34.  
  35. _, ok2 := interface{}(SortableStrings{}).(Sortable)
  36. fmt.Println("ok2", ok2)
  37. }

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


  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. type SortableStrings []string
  9.  
  10. type Sortable interface {
  11. sort.Interface
  12. Sort()
  13. }
  14.  
  15. func (self SortableStrings) Len() int {
  16. return len(self)
  17. }
  18.  
  19. func (self SortableStrings) Less(i, j int) bool {
  20. return self[i] < self[j]
  21. }
  22.  
  23. func (self SortableStrings) Swap(i, j int) {
  24. self[i], self[j] = self[j], self[i]
  25. }
  26.  
  27. func (self *SortableStrings) Sort() {
  28. sort.Sort(self)
  29. }
  30.  
  31. func main() {
  32. _, ok1 := interface{}(SortableStrings{}).(sort.Interface)
  33. fmt.Println("ok1", ok1)
  34.  
  35. _, ok2 := interface{}(&SortableStrings{}).(Sortable)
  36. fmt.Println("ok2", ok2)
  37. }

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


  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. type SortableStrings []string
  9.  
  10. type Sortable interface {
  11. sort.Interface
  12. Sort()
  13. }
  14.  
  15. func (self SortableStrings) Len() int {
  16. return len(self)
  17. }
  18.  
  19. func (self SortableStrings) Less(i, j int) bool {
  20. return self[i] < self[j]
  21. }
  22.  
  23. func (self SortableStrings) Swap(i, j int) {
  24. self[i], self[j] = self[j], self[i]
  25. }
  26.  
  27. func (self *SortableStrings) Sort() {
  28. sort.Sort(self)
  29. }
  30.  
  31. func main() {
  32. _, ok1 := interface{}(&SortableStrings{}).(sort.Interface)
  33. fmt.Println("ok1", ok1)
  34.  
  35. _, ok2 := interface{}(&SortableStrings{}).(Sortable)
  36. fmt.Println("ok2", ok2)
  37. }

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


  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. type SortableStrings []string
  9.  
  10. type Sortable interface {
  11. sort.Interface
  12. Sort()
  13. }
  14.  
  15. func (self SortableStrings) Len() int {
  16. return len(self)
  17. }
  18.  
  19. func (self SortableStrings) Less(i, j int) bool {
  20. return self[i] < self[j]
  21. }
  22.  
  23. func (self SortableStrings) Swap(i, j int) {
  24. self[i], self[j] = self[j], self[i]
  25. }
  26.  
  27. func (self *SortableStrings) Sort() {
  28. sort.Sort(self)
  29. }
  30.  
  31. func main() {
  32. ss := SortableStrings{"", "", ""}
  33. ss.Sort()
  34. fmt.Println("Sortable Strings", ss)
  35. _, ok1 := interface{}(SortableStrings{}).(sort.Interface)
  36. fmt.Println("ok1", ok1)
  37.  
  38. _, ok2 := interface{}(SortableStrings{}).(Sortable)
  39. fmt.Println("ok2", ok2)
  40.  
  41. _, ok3 := interface{}(&SortableStrings{}).(sort.Interface)
  42. fmt.Println("ok3", ok3)
  43.  
  44. _, ok4 := interface{}(&SortableStrings{}).(Sortable)
  45. fmt.Println("ok4", ok4)
  46. }


  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. type SortableStrings []string
  9.  
  10. type Sortable interface {
  11. sort.Interface
  12. Sort()
  13. }
  14.  
  15. func (self *SortableStrings) Len() int {
  16. return len(self)
  17. }
  18.  
  19. func (self *SortableStrings) Less(i, j int) bool {
  20. return self[i] < self[j]
  21. }
  22.  
  23. func (self *SortableStrings) Swap(i, j int) {
  24. self[i], self[j] = self[j], self[i]
  25. }
  26.  
  27. func (self *SortableStrings) Sort() {
  28. sort.Sort(self)
  29. }
  30.  
  31. func main() {
  32. ss := SortableStrings{"", "", ""}
  33. ss.Sort()
  34. fmt.Println("Sortable Strings", ss)
  35. _, ok1 := interface{}(SortableStrings{}).(sort.Interface)
  36. fmt.Println("ok1", ok1)
  37.  
  38. _, ok2 := interface{}(SortableStrings{}).(Sortable)
  39. fmt.Println("ok2", ok2)
  40.  
  41. _, ok3 := interface{}(&SortableStrings{}).(sort.Interface)
  42. fmt.Println("ok3", ok3)
  43.  
  44. _, ok4 := interface{}(&SortableStrings{}).(Sortable)
  45. fmt.Println("ok4", ok4)
  46. }


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

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. type SortableStrings []string
  9.  
  10. type Sortable interface {
  11. sort.Interface
  12. Sort()
  13. }
  14.  
  15. func (self SortableStrings) Len() int {
  16. return len(self)
  17. }
  18.  
  19. func (self SortableStrings) Less(i, j int) bool {
  20. return self[i] < self[j]
  21. }
  22.  
  23. func (self SortableStrings) Swap(i, j int) {
  24. self[i], self[j] = self[j], self[i]
  25. }
  26.  
  27. func (self *SortableStrings) Sort() {
  28. sort.Sort(self)
  29. }
  30.  
  31. func main() {
  32. ss := SortableStrings{"", "", ""}
  33. ss.Sort() //值变量可以访问接收器是值类型的方法
  34. fmt.Println("Sortable Strings", ss)
  35.  
  36. fmt.Println("ss : self[0] < self[1]", ss.Less(, ))
  37. fmt.Println("&ss : self[0] < self[1]", (&ss).Less(, )) //指针变量可以访问接收器是值类型的方法
  38.  
  39. _, ok1 := interface{}(ss).(sort.Interface)
  40. fmt.Println("ok1", ok1)
  41.  
  42. _, ok2 := interface{}(ss).(Sortable)
  43. fmt.Println("ok2", ok2)
  44.  
  45. _, ok3 := interface{}(&ss).(sort.Interface)
  46. fmt.Println("ok3", ok3)
  47.  
  48. _, ok4 := interface{}(&ss).(Sortable)
  49. fmt.Println("ok4", ok4)
  50.  
  51. _, ok5 := interface{}(SortableStrings{}).(sort.Interface)
  52. fmt.Println("ok5", ok5)
  53.  
  54. _, ok6 := interface{}(SortableStrings{}).(Sortable)
  55. fmt.Println("ok6", ok6)
  56.  
  57. _, ok7 := interface{}(&SortableStrings{}).(sort.Interface)
  58. fmt.Println("ok7", ok7)
  59.  
  60. _, ok8 := interface{}(&SortableStrings{}).(Sortable)
  61. fmt.Println("ok8", ok8)
  62. }

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

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

  1. package main
  2.  
  3. import (
  4. "log"
  5. )
  6.  
  7. type User struct {
  8. Name string
  9. Email string
  10. }
  11.  
  12. func (u *User) Notify() error {
  13. log.Printf("User: Sending User Email To %s<%s>\n",
  14. u.Name,
  15. u.Email)
  16.  
  17. return nil
  18. }
  19.  
  20. type Notifier interface {
  21. Notify() error
  22. }
  23.  
  24. func SendNotification(notify Notifier) error {
  25. return notify.Notify()
  26. }
  27.  
  28. func main() {
  29. user := User{
  30. Name: "AriesDevil",
  31. Email: "ariesdevil@xxoo.com",
  32. }
  33.  
  34. SendNotification(user)
  35. }

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

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

  1. _, ok1 := interface{}(user).(Notifier)
  2. fmt.Println("ok1", ok1) //false
  3.  
  4. _, ok2 := interface{}(&user).(Notifier)
  5. fmt.Println("ok2", ok2) //true
  6. SendNotification(user)

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

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "log"
  6. )
  7.  
  8. type User struct {
  9. Name string
  10. Email string
  11. }
  12.  
  13. func (u *User) Notify() error {
  14. log.Printf("User: Sending User Email To %s<%s>\n",
  15. u.Name,
  16. u.Email)
  17.  
  18. return nil
  19. }
  20.  
  21. func (u User) NameString() {
  22. u.Name = "Bob"
  23. fmt.Println("Name", u.Name)
  24. }
  25.  
  26. func (u *User) EmailString() {
  27. u.Email = "Bob@hotmail.com"
  28. fmt.Println("Email", u.Email)
  29. }
  30.  
  31. type Notifier interface {
  32. Notify() error
  33. NameString()
  34. EmailString()
  35. }
  36.  
  37. func SendNotification(notify Notifier) error {
  38. return notify.Notify()
  39. }
  40.  
  41. func main() {
  42. user := User{
  43. Name: "AriesDevil",
  44. Email: "ariesdevil@xxoo.com",
  45. }
  46.  
  47. user.NameString()
  48. user.EmailString()
  49. fmt.Println("Name", user.Name)
  50. fmt.Println("Email", user.Email)
  51.  
  52. (&user).NameString()
  53. (&user).EmailString()
  54. fmt.Println("Name", (&user).Name)
  55. fmt.Println("Email", (&user).Email)
  56.  
  57. _, ok1 := interface{}(user).(Notifier)
  58. fmt.Println("ok1", ok1) //false
  59.  
  60. _, ok2 := interface{}(&user).(Notifier)
  61. fmt.Println("ok2", ok2) //true
  62.  
  63. //SendNotification(user)
  64.  
  65. }

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. lumen response全局函数设置header

    设置header Cache-Controlreturn response()->json($return)->header('Cache-Control', 'public');

  2. 【Leetcode_easy】812. Largest Triangle Area

    problem 812. Largest Triangle Area solution: class Solution { public: double largestTriangleArea(vec ...

  3. FlappyBird

    学习CocosCreator有段时间了,现在花了两天时间写了个像素鸟的小游戏,这个游戏之前又看到过,但是不知道怎么又下架了,之前还是蛮火的游戏,想起来后去网上看了看,原来是因为侵犯了 超级玛丽 的游戏 ...

  4. 使用Vue-Router的导航守卫-无限循环问题

    我在项目里面用到了的是全局守卫,beforeEach,方便管理 不过遇到了一个问题,就是在beforeEach()中设置好判断条件后出现了无限循环的问题 当时的代码如下: router.beforeE ...

  5. 关于opencv的几个小总结

    关于opencv的几个小总结 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:opencv是一个非常好用的开源图像处理与计算机视觉支持库,但是在实际使用 ...

  6. 高级UI-RecyclerView拖拽和侧滑

    RecyclerView强大的地方在于高度的可定制,正式由于此优点,现在的项目大多使用RecyclerView,这里我们仿照QQ的功能,实现RecyclerView的拖拽和侧滑功能 功能说明 上下拖拽 ...

  7. Spring 使用日期类型

    1. 数据层数据类型依赖包  java.time.LocalDate 2.pom.xml添加依赖 <dependency> <groupId>org.thymeleaf.ext ...

  8. Memcached stats命令及核心参数

    一.stats命令 用来查看服务器的运行状态和内部数据,其中核心的参数有: 1.缓存命中率相关参数: cmd_get:总查询次数 get_hits:命中次数 get_misses:未命中次数 2.使用 ...

  9. [转帖]英特尔首次使用其3D堆叠架构演示Lakefield芯片设计

    英特尔首次使用其3D堆叠架构演示Lakefield芯片设计 http://www.chinapeace.org.cn/keji/201904/2812749.html 这段时间学习最大的收获: . 发 ...

  10. 《Mysql - 优化器是如何选择索引的?》

    一:概念 - 在 索引建立之后,一条语句可能会命中多个索引,这时,索引的选择,就会交由 优化器 来选择合适的索引. - 优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句. 二: ...