探究golang接口

今天看了《Go 语言中的方法,接口和嵌入类型》所以想对比以前对C/C++相关知识进一步理解golang的接口、指针、参数传递。

接口

根据《Go 语言中的方法,接口和嵌入类型》的描述可以看出,接口去调用结构体的方法时需要针对接受者的不同去区分,即:

  • 接收者是指针*T时,接口实例必须是指针
  • 接收者是值 T时,接口实力可以是指针也可以是值
  • 接口的定义和类型转换与接收者的定义是关联的

文章中的示例是通过接口作为函数参数的方式展现的,这里我直接使用变量来进行实验:

package main

import "fmt"

type Type struct {
     name string
}

type PType struct {
     name string
}

type Inter iInterface {
     post()
}

// 接收者非指针
func (t Type) post() {
    fmt.Println("POST")
}

// 接收者是指针
func (t *PType) post() {
    fmt.Println("POST")
}

func main()
{
    var it Inter
    //var it *Inter //接口不能定义为指针
    pty := new(Type)
    ty := {"type"}
    it = ty // 将变量赋值给接口,OK
    it.post() // 接口调用方法,OK
    it = pty // 把指针变量赋值给接口,OK
    it.post() // 接口调用方法,OK

    pty2 := new(PType)
    ty2 := {"ptype"}
    it = ty2 // 将变量赋值给接口,error
    it.post() // 接口调用方法,error
    it = pty2 // 把指针变量赋值给接口,OK
    it.post() // 接口调用方法,OK
}

看到的情况和文章中所使用的接口作为参数的情况完全一致。

根据规定接口不能定义为指针,我曾经尝试将接口定义为指针,而以提示:

cannot use user (type User) as type *Interface in assignment:

*Interface is pointer to interface, not interface

的失败结果而告终。个人从C++的经验这样理解接口,接口本身是一种引用,而声明指向引用的指针是非法的C++中会出现下面的编译错误:

error: cannot declare pointer to ‘int&’

变量和指针直接调用成功应会是golang内部类型的隐藏转换

进一步的探究,通过指针赋值的接口转换成指针是成功的 pty = t.(*Type),但是将通过指针赋值的接口转换成普通的值类型会出现下面的错误:

panic: interface conversion: main.Inter is *main.Type, not main.Type

同样,通过值赋值的接口直接转换成指针pty = t.(Type)也会出错,这也许证明了interface是引用的推断,同时也说明他不是简单的指针。

这一点让我联想到了,C++中虚函数实现多态的情况,如果想要使用多态特性,实例化的对象必须是指针或者引用。

函数

根据实验参数传递基本上和C/C++也是相同的,毕竟goc仅仅是“同父异母”而已(:-p)。即是所有的参数都是按照值进行传递的,而指针和引用因为副本所指向的内容相同,所以修改其内容同时引发原始数据的改变。所以golang中函数需要对数据进行修改需要通过指针类型进行数据传递

和函数参数传递一样,如果修改接收者是值类型的数据时,也只是修改的他的副本,而不影响他原有的数据。

由此可以理解 接收者实际传递的是一个参数,它的传递方式同样是复制



OK,先这些吧,根据自己的理解在进一步添加和修改内容,如果有错误,还请大家指出。

csdn blog换了Markdown编辑器写文章的心情确实好多了!!!!

2015-03-13

cnsworder

时间: 2024-10-20 13:55:12

探究golang接口的相关文章

golang接口的使用(练习一)

在go语言中,一个类只要实现了接口要求的所有函数,我们就说这个类实现了这个接口.golang接口赋值实现方式一:将对象实例赋值给接口 package main import "fmt" //定义一个Animal接口,实现飞和跑的功能 type Animal interface { Fly() Run() } //定义一个Bird类 type Bird struct { } //通过类实现接口的函数功能 func (bird Bird) Fly() { fmt.Println("

Golang 接口与反射知识要点

目录 Golang 接口与反射知识要点 1. 接口类型变量 2. 类型断言 3. 鸭子类型 4. 反射机制 5. reflect 包 TypeOf().ValueOf() Type().Kind() Interface() 6. 反射对象的可设置性 SetXXX(), CanSet() Elem() 7. Struct 的反射 NumField(), Type.Field(i int) Value.Field(i int) 参考文档 Golang 接口与反射知识要点 这篇文章以 Go 官方经典博

golang 接口开发入门01- 从0开始构建项目

之前写了两篇golang开发入门文章,太过潦草,赶着10.1 放假的前夕,想着还是要认真对待自己写的东西,记录学习的点滴,以后也许会忘了现在学习的东西,但是好歹留下一些文字,同时也希望能给花时间读我博客的人真正有些帮助. 前期准备 因为golang 之前断断续续学过一点,所以现在就以开发一个用户管理这样简单的功能入手.如果你现在在看我的这篇文章,你需要要具备以下知识点 1.golang 开发环境搭建 2.golang 的基本语法 3.面向对象和mvc开发思想 搭建项目 我使用eclipse作为开

golang 接口笔记

一.概念 接口类型是对其它类型行为的抽象和概括:因为接口类型不会和特定的实现细节绑定在一起,通过这种抽象的方式我们可以让我们的函数更加灵活和更具有适应能力. Go语言中接口类型的独特之处在于它是满足隐式实现的.也就是说,我们没有必要对于给定的具体类型定义所有满足的接口类型:简单地拥有一些必需的方法就足够了. 这种设计可以让你创建一个新的接口类型满足已经存在的具体类型却不会去改变这些类型的定义:当我们使用的类型来自于不受我们控制的包时这种设计尤其有用. 二.接口的声明及使用 package mai

golang 接口

接口类型是对其它类型行为的抽象和概括:因为接口类型不会和特定的实现细节绑定在一 起,通过这种抽象的方式我们可以让我们的函数更加灵活和更具有适应能力. 很多面向对象的语言都有相似的接口概念,但Go语言中接口类型的独特之处在于它是满足隐 式实现的.也就是说,我们没有必要对于给定的具体类型定义所有满足的接口类型:简单地 拥有一些必需的方法就足够了.这种设计可以让你创建一个新的接口类型满足已经存在的具 体类型却不会去改变这些类型的定义:当我们使用的类型来自于不受我们控制的包时这种设 计尤其有用. 原文地

golang接口请求方法

1.方法1:map[persistent_code: errcode:0 errmsg:ok unionid:0hY5m7YiPiSy1tmdVsiPDaItgiEiE openid:yseuqjbnfunc GetInfo(token string)(){baseurl := "https://oapi.dingtalk.com/sns/getuserinfo?sns_token="accessUrl := baseurl + tokenresponseToken,err:= htt

golang接口的封装

一.声明接口 1 type Result interface { 2 LastInsertId() (int64, error) 3 RowsAffected() (int64, error) 4 } 二.实现接口,这里却将接口作为成员变量,进而将接口的实现转换为接口的调用,仅仅是封装了接口,实际上并没有真的实现,而是坐等别人去实现 1 // 一把锁 2 // 一个结果集的假接口实现,表示需要的功能,让他人来具体实现.假装实现了某个接口,其实是调用了内部接口的对应方法 3 type driver

golang 接口interface{}、断言、switch type

第一大部分 interface{} 可以接受任何类型的对象值 获取interface{}队形的数据类型,可以使用断言,或者 switch type 来实现 // Assertion project main.go package main import ( "fmt" ) type Bag struct { Key string } type Bag2 struct { Key int } func main() { var b1 interface{} var b2 interfac

ABP官方文档翻译 3.3 仓储

 仓储 默认仓储 自定义仓储 自定义仓储接口 自定义仓储实现 基础仓储方法管理数据库连接 查询 获取单个实体 获取实体列表 关于IQueryable 自定义返回值 插入 更新 删除 其他 关于异步方法 管理数据库连接 仓储生命周期 仓储最佳实践 协调领域和数据映射层,使用类集合接口访问领域对象."(Martin Fowler) 实际上,仓储用来执行领域对象的数据库操作(实体和值类型).通常,每个对象(或聚合根)使用单独的仓储. 默认仓储 在ABP中,仓储类实现IRepository<TEn