invalid type switch guard:key :=k(type)(non-interface type dns.RR on left) 解决方案(转)

原文 :https://my.oschina.net/xinxingegeya/blog/711916

Go接口——类型断言

Java当中有instanceof这样的关键字判断类型 Go当中自然也有相应的方法来判断类型。

写法为

value, ok := em.(T) 

如果确保em是同类型的时候可以直接使用

value := em.(T)

一般用于switch语句中

  • em代表要判断的变量
  • T代表要判断的类型
  • value代表返回的值
  • ok代表是否为该类型

CASE 一

em必须为interface类型才可以进行类型断言

比如下面这段代码,

s := "hello world"
if v, ok := s.(string); ok {
	fmt.Println(v)
}

运行报错, invalid type assertion: s.(string) (non-interface type string on left)

在这里只要是在声明时或函数传进来的参数不是interface类型那么做类型断言都是回报 non-interface的错误的 所以我们只能通过将s作为一个interface{}的方法来进行类型断言,如下代码所示:

x := "hello world"
if v, ok := interface{}(x).(string); ok { // interface{}(x):把 x 的类型转换成 interface{}
	fmt.Println(v)
}

将s显示的转换为interface{}接口类型则可以进行类型断言了

CASE 二

当函数作为参数并且被调用函数将参数类型指定为interface{}的时候是没有办法直接调用该方法的,如下面代码,

package mainimport ("fmt")
func ServeHTTP(s string) {
	fmt.Println(s)}
	type Handler func(string)
	func panduan(in interface{}) {
	Handler(in)("wujunbin")
}func main() {
	panduan(Handler(ServeHTTP))
}

运行报错,

./assert.go:14: cannot convert in (type interface {}) to type Handler: need type assertion

改正如下,

package main
import (
	"fmt"
)
func ServeHTTP(s string) {
	fmt.Println(s)
}
type Handler func(string) //使用 type 定义一个函数类型
func panduan(in interface{}) {
	v, ok := in.(Handler)
	if ok {
		v("hello world")
	} else {
		panic("assert fail")
	}
}
func main() {
	panduan(Handler(ServeHTTP))
}

只有让传进来的in参数先与Handler进行类型判断如果返回值是OK则代表类型相同才能进行对应的方法调用。

CASE 三

进行类型断言之后如果断言成功,就只能使用该类型的方法。 比如对一个结构体S进行与A接口断言,S实际上实现了A B两个接口,A interface 具有 a()方法,B interface 具有 b()方法,如果结构体S作为参数被传入一个函数中并且在该函数中是interface{}类型,那么进行与A的类型断言之后就只能调用a()而不能调用b(),因为编译器只知道你目前是A类型却不知道你目前也是B类型。看下面这个例子,

package main
import (
	"fmt"
)
type InterfaceA interface {
	AA()
}
type InterfaceB interface {
	BB()
}
// Won 实现了接口 AA 和 BB
type Won struct{}
func (w Won) AA() {
	fmt.Println("AA")
}
func (w Won) BB() {
	fmt.Println("BB")
}
func info(in interface{}) {
	//必须经过 类型断言,才能调用相应的方法
	v, ok := in.(InterfaceA) //必须进行相应的断言才能进行函数的调用,不然编译器不知道是什么具体类型
	if ok {
		v.AA()
	} else {
		fmt.Println("assert fail")
	}
}func main() {
	var x InterfaceA = Won{}
	info(x)
	var y Won = Won{}
	info(y)
}

CASE 四

switch与类型断言的结合使用还是比较方便的,如下所示,

package main
import (
	"fmt"
)
type Element interface{}
func main() {
	var e Element = 100
	switch value := e.(type) {
	case int:
		fmt.Println("int", value)
	case string:
		fmt.Println("string", value)
	default:
		fmt.Println("unknown", value)
	}
}

========END========

阅读更多
相关热词
换一批

没有更多推荐了,返回首页