为什么golang自定义错误变量有多种类型
我是一个新的地鼠,如果我定义一个自定义错误,我会被变量类型弄糊涂为什么golang自定义错误变量有多种类型,go,types,error-handling,Go,Types,Error Handling,我是一个新的地鼠,如果我定义一个自定义错误,我会被变量类型弄糊涂 import ( "fmt" "reflect" ) // custom errors type myError struct { msg string } func (m *myError) Error() string { return m.msg } func errorGen() error
import (
"fmt"
"reflect"
)
// custom errors
type myError struct {
msg string
}
func (m *myError) Error() string {
return m.msg
}
func errorGen() error {
return &myError{"custom error"}
}
生成新错误并检查其类型
func main() {
e := errorGen()
fmt.Println(reflect.TypeOf(e).Kind()) // type = pointer
// first type assertion
_, ok := e.(error)
if ok {
fmt.Println("type assertion error") // type = error
}
// second type assertion
_, ok = e.(*myError)
if ok {
fmt.Println("type assertion *myError") // type = pointer
}
}
因此,在上面的代码中,变量“e”同时显示两种类型。
e的类型到底是什么?为什么“error”是一个接口,也可以用作返回类型
多谢各位
预声明类型错误定义为
type error interface {
Error() string
}
它是表示错误条件的常规接口,
使用nil值表示无错误
接口类型指定称为其接口的方法集。A.
接口类型的变量可以使用方法存储任何类型的值
集,它是接口的任何超集。这样的一种类型被称为
实现接口
e
实现预先声明的接口类型error
// first type assertion
_, ok := e.(error)
if ok {
fmt.Println("type assertion error") // type = error
}
// second type assertion
_, ok = e.(*myError)
if ok {
fmt.Println("type assertion *myError") // type = pointer
}
e
的具体类型是指向类型myError
的指针
// first type assertion
_, ok := e.(error)
if ok {
fmt.Println("type assertion error") // type = error
}
// second type assertion
_, ok = e.(*myError)
if ok {
fmt.Println("type assertion *myError") // type = pointer
}
两个类型断言都为true(ok
为true
)
预声明类型错误定义为
type error interface {
Error() string
}
它是表示错误条件的常规接口,
使用nil值表示无错误
接口类型指定称为其接口的方法集。A.
接口类型的变量可以使用方法存储任何类型的值
集,它是接口的任何超集。这样的一种类型被称为
实现接口
e
实现预先声明的接口类型error
// first type assertion
_, ok := e.(error)
if ok {
fmt.Println("type assertion error") // type = error
}
// second type assertion
_, ok = e.(*myError)
if ok {
fmt.Println("type assertion *myError") // type = pointer
}
e
的具体类型是指向类型myError
的指针
// first type assertion
_, ok := e.(error)
if ok {
fmt.Println("type assertion error") // type = error
}
// second type assertion
_, ok = e.(*myError)
if ok {
fmt.Println("type assertion *myError") // type = pointer
}
这两种类型断言都是真的(
ok
istrue
)。必须区分变量的“静态类型”和“动态类型”
Go中的每个变量都有一个静态类型。例如:
- 声明
后,a:=5
的静态类型是a
,这就是int
的全部内容a
- 代码中
的静态类型是e
(因为error
返回的就是这种类型)errorGen
- 您可以像下面这样明确地描述静态类型:
var b uint16=9
error
作为其静态类型;你的e
就是一个例子。现在,接口类型变量的全部用途是存储实现该接口的各种类型的值。所以一个不是nil的接口变量不知何故“包含”了另一个变量(实际上是一个值)。此包含值的类型可以是实现接口的任何类型。所包含值的类型为“动态类型”。
类型断言允许您提取此动态类型的值。您必须区分变量的“静态类型”和“动态类型” Go中的每个变量都有一个静态类型。例如:
- 声明
后,a:=5
的静态类型是a
,这就是int
的全部内容a
- 代码中
的静态类型是e
(因为error
返回的就是这种类型)errorGen
- 您可以像下面这样明确地描述静态类型:
var b uint16=9
error
作为其静态类型;你的e
就是一个例子。现在,接口类型变量的全部用途是存储实现该接口的各种类型的值。所以一个不是nil的接口变量不知何故“包含”了另一个变量(实际上是一个值)。此包含值的类型可以是实现接口的任何类型。所包含值的类型为“动态类型”。
类型断言允许您提取此动态类型的值。为什么e的统计类型是
error
不是指针
考虑到errorGen
正在返回一个地址查看errorGenfunc errorGen()error
它返回一个错误
。返回的类型是函数签名中的类型。函数体在错误中存储*myError,并返回该错误。函数的返回类型仅由函数签名决定。无论您在return
之后写什么,对于静态返回类型(只要它编译)都不重要。为什么e的统计类型是error
而不是指针考虑到errorGen
正在返回一个地址看看errorGenfunc errorGen()error
它返回一个error
。返回的类型是函数签名中的类型。函数体在错误中存储*myError,并返回该错误。函数的返回类型仅由函数签名决定。无论您在return
之后写什么,对于静态返回类型来说都不重要(只要它能够编译)。