在 Go 中,类型可以定义接收此类型的函数,即方法。每个类型都有接口,意味着对那个类型定义了方法集合。

下面定义了结构体类型 S 以及它的两个方法:

type S struct { i int }
func (p *S) Get() int { return p.i }
func (p *S) Put(v int) { p.i = v }

方法

方法就是有接收者的函数。

可以在除了非本地类型(包括内建类型,比如 int)的任意类型上定义方法。然而可以为内建类型定义别名,然后就可以为别名定义方法。如

type Foo int // 为 int 定义别名 Foo
func (self Foo) Emit() {
fmt.Printf("%v", self)
}

接口

接口定义为一个方法的集合。方法包含实际的代码。换句话说,一个接口就是定义,而方法就是实现。因此,接收者不能定义为接口类型,这样做的话会引起 invalid receiver type … 的编译器错误。

来自语言说明书的权威内容:

接收者类型必须是T 或*T,这里的 T 是类型名。 T 叫做接收者基础类型或简称基础类型。基础类型一定不能是指针或接口类型,并且定义在与方法相同的包中。

// 定义了有两个方法的接口 I,结构 S 实现了此接口
type I interface {
Get() int
Put( int)
}

可以定义接口类型的变量(接口值)作为函数的参数,实现了此接口的类型的变量可以作为实参传递给该接口变量并调用其方法。

func f(p I) {
fmt.Println(p.Get())
p.Put(1)
} var s S
f(&s) // S 类型的变量 s 作为实参传给接口。取地址是因为在 s 的指针上定义了方法,这样可以修改 s;
// 如果在 s 上定义方法,则修改的只是 s 的副本

在 Go 中创建指向接口的指针是无意义的。创建接口值的指针也是非法的。

接口类型判断

在 Go 中,要判断传递给接口值的变量类型,可以在使用 type switch 得到。(type)只能在 switch 中使用。

// 另一个实现了 I 接口的 R 类型
type R struct { i int }
func (p *R) Get() int { return p.i }
func (p *R) Put(v int) { p.i = v } func f(p I) {
switch t := p.(type) { // 判断传递给 p 的实际类型
case *S: // 指向 S 的指针类型
case *R: // 指向 R 的指针类型
case S: // S 类型
case R: // R 类型
default: //实现了 I 接口的其他类型
}
}

若要在 switch 外判断一个接口类型是否实现了某个接口,可以使用“逗号 ok ”。

value, ok := Interfacevariable.(implementType)

其中 Interfacevariable 是接口变量(接口值),implementType 为实现此接口的类型,value 返回接口变量实际类型变量的值,如果该类型实现了此接口返回 true

type I interface{ // 有一个方法的接口 I
Get() Int
} type Int int // Int 类型实现了 I 接口
func (i Int) Get() Int{
return i
} var myint Int = 5
var inter I = myint // 变量赋值给接口
val, ok := inter.(Int)
fmt.Printf("%v, %v", val, ok) // 输出为:5,true

空接口

每种类型都能匹配到空接口:interface{}。空接口类型对方法没有任何约束(因为没有方法),它能包含任意类型,也可以实现到其他接口类型的转换。如果传递给该接口的类型变量实现了转换后的接口则可以正常运行,否则出现运行时错误。

func g(si interface{}) int {
return si.(I).Get()
}
s = new(S)
g(s) // (I) 将 si 转换到 I 类型的接口,s 实现了 Get 方法,因此可以调用 g() i := 5
g(i) // 运行时出错,因为 int 型没有 Get 方法

还可以在接口中列出另一个接口,如

type Interface interface {
sort.Interface // 另一个接口
Push(x interface{})
Pop() interface{}
}

自省和反射

Go 方法、接口的更多相关文章

  1. go 函数 方法 接口

    概论 函数 方法 接口 概论 方法在编译时静态绑定,依托于具体的类型 接口对应的方法是在运行时动态绑定 进程内初始化顺序 初始化导入包的常量和变量(可以导出的变量)--->包的init函数,不同 ...

  2. JVM 专题十四:本地方法接口

    1. 本地方法接口 2. 什么是本地方法? 简单来讲,一个Native Method就是一个Java调用非Java代码的接口.一个Native Method是这样一个java方法:该方法的实现由非Ja ...

  3. JVM--先说本地方法接口

    本地方法接口 在讲Java虚拟机运行时数据区中本地方法栈之前,我们先来说说运行时数据区之外的一个叫本地方法接口的东西简称JNI(Java Native Interface) 简单来讲,一个Native ...

  4. C# 工厂模式+虚方法(接口、抽象方法)实现多态

    面向对象语言的三大特征之一就是多态,听起来多态比较抽象,简而言之就是同一行为针对不同对象得到不同的结果,同一对象,在不同的环境下得到不同的状态. 实例说明: 业务需求:实现一个打开文件的控制台程序的d ...

  5. Java8函数式接口/Lambda表达式/接口默认方法/接口静态方法/接口冲突方法重写/lambda表达式指定泛型类型等

    一:函数式接口 1.函数式接口的概念就是此接口必须有且只能有一个抽象方法,可以通过@FunctionalInterface来显示规定(类似@Override),但是没有此注解的但是只有一个抽象方法的接 ...

  6. OpenJDK源码研究笔记(十四):三种经典的设计方法,接口,接口-抽象类-具体实现类,接口-具体实现类

    在研究OpenJDK源码过程中,我发现常用的设计方法就是2种:接口,接口-抽象类-具体实现类 . 在一些其它开源框架和业务开发中,经常存在着第3种设计,接口-具体实现类. 1.只有接口,没有实现类. ...

  7. C# 3.0 扩展方法&接口

    namespace ExtensionInterfaceMethod { class Program { static void Main(string[] args) { //使用接口变量来调用扩展 ...

  8. jvm入门及理解(五)——运行时数据区(虚拟机栈)和本地方法接口

    一.虚拟机栈背景 由于跨平台性的设计,java的指令都是根据栈来设计的.不同平台CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要 ...

  9. jvm-本地方法接口

    什么是本地方法 简单地讲,一个Native Methodt是一个Java调用非Java代码的接囗.一个Native Method是这样一个Java方法:该方法的实现由非Java语言实现,比如C.这个特 ...

  10. Golang 函数 方法 接口的简单介绍

    函数 函数是基本的代码块,通常我们会将一个功能封装成一个函数,方便我们调用,同时避免代码臃肿复杂. 函数的基本格式 func TestFunc(a int, b string) (int, strin ...

随机推荐

  1. 【Tomcat】1.Tomcat在Windows系统的安装和使用

    1.下载与安装 安装Tomcat的[前提条件]是安装好JDK或者JRE(本文略过)Tomcat在Windows系统中可以通过[压缩包]或[安装包]来安装建议使用[安装包]来简化安装步骤登录官网http ...

  2. 利用core_pattern实现core文件的配置和管理

    参考:https://xz.aliyun.com/t/1098 这里所说的core_pattern 指的是:/proc/sys/kernel/core_pattern. 我们知道在Linux系统中,如 ...

  3. 72、salesforce call RESTful 的方式

    通过Chrome的Postman 来call salesforce的restful api https://login.salesforce.com/services/oauth2/token?gra ...

  4. PHP缓存技术相关

    全页面静态化缓存也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程.此种方式,在CMS系统中比较常见,比如dedecms:一种比较常用的实现方式是用输 ...

  5. dubbo超时原理以及解决方案

    dubbo超时原理以及解决方案 本篇主要记录dubbo中关于超时的常见问题,实现原理,解决的问题 超时问题 为了检查对dubbo超时的理解,尝试回答如下几个问题,如果回答不上来或者不确定那么说明此处需 ...

  6. CPython,PyPy?Python和这两个东西有什么关系

    https://blog.csdn.net/fu6543210/article/details/90770794 python是一种编程语言.但这种语言有多种实现,而且与其他语言不同,python并没 ...

  7. testNG官方文档翻译-5 测试方法,测试类和测试组

    5.1 - 测试方法 测试方法是被 @Test注解的方法.这些方法的返回值会被忽略,除非在testng.xml中将allow-return-values设置为true. <suite allow ...

  8. JPA 派生标识符的两种实现方式

    方法一:@Entity@IdClass(ModuleId.class)public class Module { @Id private Integer index; @Id @ManyToOne p ...

  9. ABTest介绍及abtest流量切换实现

    本文为学习abtest切流方案方便以后查看大部分内容转载自原文 https://blog.csdn.net/tanweii163/article/details/80543083 互联网公司的业务发展 ...

  10. Springboot+mybatis+dbcp+mysql简单集成

    1.添加依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>m ...