• go学习-接口


    接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。

    接口类型

    在Go语言中接口(interface)是一种类型,一种抽象的类型。
    interface是一组method的集合。

    接口的定义

    Go语言提倡面向接口编程。
    每个接口由数个方法组成,接口的定义格式如下:

    type 接口类型名 interface{
        方法名1( 参数列表1 ) 返回值列表1
        方法名2( 参数列表2 ) 返回值列表2
        …
    }
    
    • 接口名:使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出该接口的类型含义。
    • 方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
    • 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。

    实现接口的条件

    一个对象只要全部实现了接口中的方法,那么就实现了这个接口。
    换句话说,接口就是一个需要实现的方法列表。

    接口类型变量

    接口类型变量能够存储所有实现了该接口的实例。

    func main() {
    	var x Sayer // 声明一个Sayer类型的变量x
    	a := cat{}  // 实例化一个cat
    	b := dog{}  // 实例化一个dog
    	x = a       // 可以把cat实例直接赋值给x
    	x.say()     // 喵喵喵
    	x = b       // 可以把dog实例直接赋值给x
    	x.say()     // 汪汪汪
    }
    

    值接收者和指针接收者实现接口的区别

    使用值接收者

    package main
    
    import "fmt"
    type Mover interface {
    	move()
    }
    
    type dog struct {}
    func (d dog) move() {
    	fmt.Println("狗会动")
    }
    func main() {
    	var x Mover
    	var wangcai = dog{} // 旺财是dog类型
    	x = wangcai         // x可以接收dog类型
    	x.move()
    	var fugui = &dog{}  // 富贵是*dog类型
    	x = fugui           // x可以接收*dog类型
    	x.move()
    }
    

    结果:不管dog是结构体还是结构体指针类型的变量都可以赋值给该接口变量。因为Go语言中有对指针类型变量求值的语法糖,dog指针fugui内部会自动求值*fugui

    使用指针接收者实现接口

    package main
    
    import "fmt"
    type Mover interface {
    	move()
    }
    
    type dog struct {}
    func (d *dog) move() {
    	fmt.Println("狗会动")
    }
    func main() {
    	var x Mover
    	var wangcai = dog{} // 旺财是dog类型
    	x = wangcai         // x可以接收dog类型
    	x.move()
    	var fugui = &dog{}  // 富贵是*dog类型
    	x = fugui           // x可以接收*dog类型
    	x.move()
    }
    

    结果:此时实现Mover接口的是dog类型,所以不能给x传入dog类型的wangcai,此时x只能存储dog类型的值。

    接口嵌套

    接口与接口间可以通过嵌套创造出新的接口。

    // Sayer 接口
    type Sayer interface {
    	say()
    }
    
    // Mover 接口
    type Mover interface {
    	move()
    }
    
    // 接口嵌套
    type animal interface {
    	Sayer
    	Mover
    }
    type cat struct {
    	name string
    }
    
    func (c cat) say() {
    	fmt.Println("喵喵喵")
    }
    
    func (c cat) move() {
    	fmt.Println("猫会动")
    }
    
    func main() {
    	var x animal
    	x = cat{name: "花花"}
    	x.move()
    	x.say()
    }
    

    空接口

    空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。

    空接口类型的变量可以存储任意类型的变量。
    func main() {
    	// 定义一个空接口x
    	var x interface{}
    	s := "Hello 沙河"
    	x = s
    	fmt.Printf("type:%T value:%v
    ", x, x)
    	i := 100
    	x = i
    	fmt.Printf("type:%T value:%v
    ", x, x)
    	b := true
    	x = b
    	fmt.Printf("type:%T value:%v
    ", x, x)
    }
    

    空接口作为函数的参数
    package main
    
    import "fmt"
    // 空接口作为函数参数
    func show(a interface{}) {
    	fmt.Printf("type:%T value:%v
    ", a, a)
    }
    func main() {
    	show("字符串")
    	show(10)
    	show(true)
    }
    

    空接口作为map的值

    使用空接口实现可以保存任意值的字典。

    package main
    
    import "fmt"
    // 空接口作为函数参数
    func show(a interface{}) {
    	fmt.Printf("type:%T value:%v
    ", a, a)
    }
    func main() {
    	// 空接口作为map值
    	var studentInfo = make(map[string]interface{})
    	studentInfo["name"] = "沙河娜扎"
    	studentInfo["age"] = 18
    	studentInfo["married"] = false
    	fmt.Println(studentInfo)
    }
    

    所有博客均为自己学习的笔记。如有错误敬请理解。
  • 相关阅读:
    English 2
    速算24点
    心理学1
    从微服务到函数式编程
    034 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 01 流程控制概述
    033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结
    032 01 Android 零基础入门 01 Java基础语法 03 Java运算符 12 运算符和if-else条件语句的综合案例——闰年问题
    031 01 Android 零基础入门 01 Java基础语法 03 Java运算符 11 运算符的优先级
    030 01 Android 零基础入门 01 Java基础语法 03 Java运算符 10 条件运算符
    029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑“非”运算符
  • 原文地址:https://www.cnblogs.com/tangtang-benben/p/15079425.html
Copyright © 2020-2023  润新知