对Golang interface的理解

理解golang的interface主要在于以下两点:

  • interface是方法的集合
  • interface是一种类型

简单示例

package main

import "fmt"

type Animal interface {
    Speak() string
}

type Cat struct{}
func (c Cat) Speak() string {
    return "cat"
}

type Dog struct{}
func (d Dog) Speak() string {
    return "dog"
}

func Test(params interface{}) {
    fmt.Println(params)
}

func main() {
    animals := []Animal{Cat{}, Dog{}}
    for _, animal := range animals {
        fmt.Println(animal.Speak())
    }

        Test("string")
    Test(123)
    Test(true)
}

以上代码中,定义了Animal为接口,而Cat和Dog两个结构体分别实现了接口中定义的方法。当interface{}作为函数形参时,可以接受不同类型的参数。

指针与interface

如果将上述代码的:

func (c Cat) Speak() string {
    return "cat"
}

修改为:

func (c *Cat) Speak() string {
    return "cat"
}

再次运行源代码,就会出现以下错误:

cannot use Cat literal (type Cat) as type Animal in array or slice literal:
Cat does not implement Animal (Speak method has pointer receiver)

这是因为程序认为Cat并未实现Speak()方法, 而是由 *Cat 实现的。这说明结构体在实现接口方法时并不会隐式转换类型。

interface 数组

interface{} 作为函数形参和 []interface{} 作为形参有很大区别,示例如下:

package main

import (
    "fmt"
)

func PrintAll(vals []interface{}) {
    for _, val := range vals {
        fmt.Println(val)
    }
}

func main() {
    names := []string{"stanley", "david", "oscar"}
    PrintAll(names)
}

以上代码是无法正常运行的,错误提示为:

cannot use names (type []string) as type []interface {} in argument to PrintAll

这说明对接口数组赋值前,必须多一个类型转换操作,正确代码如下:

package main

import (
    "fmt"
)

func PrintAll(vals []interface{}) {
    for _, val := range vals {
        fmt.Println(val)
    }
}

func main() {
    names := []string{"stanley", "david", "oscar"}
    vals := make([]interface{}, len(names))
    for i, v := range names {
        vals[i] = v
    }
    PrintAll(vals)
}

以上是关于interface使用的基础内容。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 8,449评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,312评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,041评论 25 709
  • 这是一个晴朗的日子。 罗德深和高德爽打了一架。原因是两家的狗打了一架。人仗狗势,两人打了起来。 罗德深是屠夫。吃肉...
    scumalapert阅读 1,534评论 0 0
  • HSET命令可以设置hash中一个field的值: HGET命令可以获取hash中一个field的值: HMSET...
    yingzong阅读 2,361评论 0 0