美文网首页EasyHacking
对Golang interface的理解

对Golang interface的理解

作者: EasyHacking | 来源:发表于2017-06-27 20:26 被阅读0次

    理解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使用的基础内容。

    相关文章

      网友评论

        本文标题:对Golang interface的理解

        本文链接:https://www.haomeiwen.com/subject/peaecxtx.html