Golang学习笔记-接口和错误

接口

Go接口定义了方法后,其它类型只要实现了这些方法就是实现了接口。Go语言中接口类型的独特之处在于它是满足隐式实现的鸭子类型。所谓鸭子类型说的是:只要走起路来像鸭子,叫起来也像鸭子,那么就可以把它当作鸭子。

type Person interface {
    speak()
}

type Student struct {

}

type Worker struct {

}

func (student Student) speak(){
    println("I am student")
}

func (worker Worker) speak(){
    println("I am worker")
}

func main() {
    var person Person
    person=Worker{}
    person.speak()//I am worker

    person=Student{}
    person.speak()//I am student
}

有时候对象和接口之间太灵活了,导致我们需要人为地限制这种无意之间的适配。常见的做法是定义一个含特殊方法来区分接口。比如runtime包中的Error接口就定义了一个特有的RuntimeError方法,用于避免其它类型无意中适配了该接口:

type Error interface {
	error

	// RuntimeError is a no-op function but
	// serves to distinguish types that are run time
	// errors from ordinary errors: a type is a
	// run time error if it has a RuntimeError method.
	RuntimeError()
}

在Go中只有interface的类型和值都为nil时,interface==nil才为true,所以我们在函数中返回一个interface时,如果想返回nil,需要直接返回nil而不是返回结构体nil指针。

func main() {
	var data *byte
	var data2 interface{}
	data2=data
	println(data2==nil)//false
	data2=nil
	println(data2==nil)//true
}

类型断言

类型断言是将接口类型转换为具体类型,类型断言分为安全类型断言和非安全类型断言,非安全类型断言失败时会发生异常,安全类型断言则可以通过返回值判断类型断言是否失败。

type MyInterface interface {
	sayHello()
}

type MyStruct struct {

}

func (obj *MyStruct) sayHello(){
	println("hello")
}

func NewMyStruct() MyInterface{
	return &MyStruct{}
}

func main() {
	//安全类型断言
	obj1,ok:=NewMyStruct().(*MyStruct)
	if ok{
		obj1.sayHello()
	}

	//非安全类型断言
	obj2:=NewMyStruct().(*MyStruct)
	obj2.sayHello()
}

错误

错误是Go的内置接口,其定义如下:

type error interface {
	Error() string
}

对于简单的错误,我们可以使用内置的errors.New生成一个errorString,对于复杂的错误,我们可以新建一个结构体实现error接口。

func divide(varDividee int, varDivider int) (int,error) {
    if varDivider == 0 {
        return 0,errors.New("the divider is zero")
    } else {
        return varDividee / varDivider, nil
    }
}

func main(){
    result,err:=divide(10,0)
    if err!=nil{
        fmt.Println(err)
    }else{
        fmt.Printf("result=%d\n",result)
    }
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页