Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么golang自定义错误变量有多种类型_Go_Types_Error Handling - Fatal编程技术网

为什么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
is
true
)。

必须区分变量的“静态类型”和“动态类型”

Go中的每个变量都有一个静态类型。例如:

  • 声明
    a:=5
    后,
    a
    的静态类型是
    int
    ,这就是
    a
    的全部内容
  • 代码中
    e
    的静态类型是
    error
    (因为
    errorGen
    返回的就是这种类型)
  • 您可以像下面这样明确地描述静态类型:
    var b uint16=9
现在Go中有了接口类型<代码>错误就是这样一种接口类型,请参见Peter的答案。一些变量将
error
作为其静态类型;你的
e
就是一个例子。现在,接口类型变量的全部用途是存储实现该接口的各种类型的值。所以一个不是nil的接口变量不知何故“包含”了另一个变量(实际上是一个值)。此包含值的类型可以是实现接口的任何类型。所包含值的类型为“动态类型”。
类型断言允许您提取此动态类型的值。

您必须区分变量的“静态类型”和“动态类型”

Go中的每个变量都有一个静态类型。例如:

  • 声明
    a:=5
    后,
    a
    的静态类型是
    int
    ,这就是
    a
    的全部内容
  • 代码中
    e
    的静态类型是
    error
    (因为
    errorGen
    返回的就是这种类型)
  • 您可以像下面这样明确地描述静态类型:
    var b uint16=9
现在Go中有了接口类型<代码>错误就是这样一种接口类型,请参见Peter的答案。一些变量将
error
作为其静态类型;你的
e
就是一个例子。现在,接口类型变量的全部用途是存储实现该接口的各种类型的值。所以一个不是nil的接口变量不知何故“包含”了另一个变量(实际上是一个值)。此包含值的类型可以是实现接口的任何类型。所包含值的类型为“动态类型”。
类型断言允许您提取此动态类型的值。

为什么e的统计类型是
error
不是
指针
考虑到
errorGen
正在返回一个地址查看errorGen
func errorGen()error
它返回一个
错误
。返回的类型是函数签名中的类型。函数体在错误中存储*myError,并返回该错误。函数的返回类型仅由函数签名决定。无论您在
return
之后写什么,对于静态返回类型(只要它编译)都不重要。为什么e的统计类型是
error
而不是
指针
考虑到
errorGen
正在返回一个地址看看errorGen
func errorGen()error
它返回一个
error
。返回的类型是函数签名中的类型。函数体在错误中存储*myError,并返回该错误。函数的返回类型仅由函数签名决定。无论您在
return
之后写什么,对于静态返回类型来说都不重要(只要它能够编译)。