7.2 go接口执行机制 摘自《go语言学习笔记》

1,接口使用一个名为itab的结构存储运行期所需的相关类型信息

type iface struct {
	tab *itab //类型信息
	data unsafe.Pointer //实际对象指针
}

type itab struct {
	inter *interfacetype //接口类型
	_type *_type		//实际对象类型
	fun []uintptr //实际对象方法地址
}

2,利用调试器,可以查看这些结构存储的具体内容

type Ner interface {
	a()
	b(int)
	c(string) string
}

type N int

func(N) a(){}
func(*N)b(int) {}
func(*N)c(string) string {return ""}

func main() {
	var n N
	var t Ner = &n

	t.a()
}

3,对象赋值给接口变量时,会复制该对象

4,类型推断可将接口还原为原始类型,或用来判断是否实现了某个更具体的接口类型,使用ok-idiom模式,即使失败也不会引发panic

package main

import (
	"fmt"
)
type data int 

func(d data) String() string {
	return fmt.Sprintf("data:%d",d)
}

func main(){
	var d data = 15
	var x interface{} = d

	if n,ok := x.(fmt.Stringer);ok { //转换为更具体的类型
		fmt.Println(n)
	}

	if d2,ok := x.(data);ok { //转换为原始类型
		fmt.Println(d2)
	}

	e:=x.(error)
	fmt.Println(e)
}

5,使用switch在多种类型间做出推断匹配,使空接口有更多发挥空间。注意:type switch不支持fallthrought。

package main
import "fmt"
func main (){
	var x interface {} = func(x int) string {
		return fmt.Sprintf("d:%d",x)
	}

	switch v:=x.(type) { //局部变量v是类型转换后的结果

	case nil:
		fmt.Println("nil")
	case *int:
		fmt.Println(*v)
	case func(int)string:
		fmt.Println(v(100))
	case fmt.Stringer:
		fmt.Println(v)
	default:
		fmt.Println("unknow")

	}
}

6,技巧:定义函数类型,让相同签名的函数自动实现某个接口

package main

import "fmt"

type FuncString func() string

func(f FuncString) String() string {
	return f()
}
func main (){
	var t fmt.Stringer = FuncString(func() string {
		return "hello world"
	})
	fmt.Println(t)
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值