当前位置: 首页 > 工具软件 > interface > 使用案例 >

go中interface{}作为参数

田佐
2023-12-01

go中interface定义

Go 语言中的接口是一组方法的组合,它是 Go 语言的重要组成部分。简单的说,interface是一组method签名的组合,我们通过interface来定义对象的一组行为。interface 是一种类型,定义如下:

type Person interface {
    Eat(food string) 
}

它的定义可以看出来用了 type 关键字,更准确的说 interface 是一种具有一组方法的类型,这些方法定义了 interface 的行为

golang接口定义不能包含变量,但是允许不带任何方法,这种类型的接口叫 empty interface

如果一个类型实现了一个interface中所有方法,我们就可以说该类型实现了该interface。所以我们的所有类型都实现了empty interface,因为任何一种类型至少实现了0个方法。并且go中并不像java中那样需要显式关键字来实现interface,只需要实现interface包含的方法即可。

实现接口

Go语言中实现接口就是隐式的,只要实现了接口中的所有函数,即认为实现了接口。举例说明:

type error interface {
    Error() string
}
type RPCError struct {
    Code    int64
    Message string
}

func (e *RPCError) Error() string {
    return fmt.Sprintf("%s, code=%d", e.Message, e.Code)
}

上面的代码,并没有error接口的影子,我们只需要实现Error() string方法就实现了error接口。

Go中,实现接口的所有方法就隐式地实现了接口。我们使用上述 RPCError 结构体时并不关心它实现了哪些接口;Go 语言只会在传递参数、返回参数以及变量赋值时才会对某个类型是否实现接口进行检查。

Go语言的这种写法很方便,不用引入包依赖。但是interface底层实现的时候会动态检测也会引入一些问题:

  • 性能下降。使用interface作为函数参数,runtime 的时候会动态的确定行为。使用具体类型则会在编译期就确定类型。
  • 不能清楚的看出struct实现了哪些接口,需要借助ide或其它工具。

两种接口

空interface

非空interface

范例

函数的传入参数实现接口

package main

import "fmt"

type Reader interface {
    Read() int
}

type MyStruct struct {
    X, Y int
}

func (m *MyStruct) Read() int {
    return m.X + m.Y
}

func run(r Reader) {
    fmt.Println(r.Read())
}

func main() {
    s := &MyStruct{3, 4}
    run(s)
}

输出:

7

分析:
        因为*MyStruct实现了Read方法,因此&MyStruct实现了Reader接口,所以把*MyStruct作为参数调用run时候,&MyStruct{3, 4}就自动实现了Reader接口,因此run里可以用r.Read()来调用接口的方法.

函数的穿出参数实现接口

package main

import "fmt"

type Sumer interface {
    Sum() int
}

type MyStruct struct {
    X, Y int
}

func (this *MyStruct) Sum() int {
    return this.X + this.Y
}

func New(a, b int) Sumer {
    return &MyStruct{a, b}
}

func main() {
    m := New(3, 4)
    s := m.Sum()
    fmt.Println(s)
}


输出

7

分析:

可以看出,因为*MyStruct实现了Sum方法,因此&MyStruct实现了Sumer接口;

空接口用于传入、传出参数


import "fmt"

type Reader interface {
    Read() int
}

type MyStruct struct {
    X, Y int
}

func (m *MyStruct) Read() int {
    return m.X + m.Y
}

func run(r interface{}) {
    // 会报错
    //fmt.Println(r.Read())
    fmt.Println(r)
    fmt.Printf("%T\n", r)
}

func main() {
    s := &MyStruct{3, 4}
    run(s)
}

输出
&{3 4}
*main.MyStruct

分析:

如果把上面例子中注释去掉,则会报错;

./example.go:19: r.Read undefined (type interface {} is interface with no methods)

参考

https://segmentfault.com/a/1190000038552939

https://cyent.github.io/golang/method/interface_argv_interface/

https://blog.csdn.net/hyl999/article/details/76573378

 类似资料: