Go语言编程:创建error的几种方式

2023-07-0216:47:19编程语言入门到精通Comments819 views字数 2219阅读模式

Go语言函数(或方法)是支持多个返回值的,因此在Go语言的编程哲学中,函数的返回值的最后一个通常都是error类型:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

//标准os包下的函数
func Open(name string) (*File, error) {
 return OpenFile(name, O_RDONLY, 0)
}

error类型作为函数的最后一个返回值,其作用在于告诉调用者函数在执行过程是否发生错误,当返回的error值为nil,表示函数正常执行。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

其实,error类型本质上是一个Go内置的接口,其定义如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

type error interface {
 Error() string
}

从上面error的定义可以看到error接口只有一个Error()方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

遵循着Go语言的编程哲学,当我们开发自己的函数时最好也把error作为函数的最后一个返回值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

即然要返回error类型,那么就必须先创建error类型,怎么创建呢?在这篇文章我们简单学习三种创建error类型的方式。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

使用errors包

Go标准库errors包为了我们提供了一个最简单的error接口实现:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

//errors包errors.go文件
type errorString struct {
 s string
}

func (e *errorString) Error() string {
 return e.s
}

从上面的定义可以看到errorString实现了error接口,且参数非常简单,只有一个文本信息,通过errors.New()函数可以创建一个errorString类型:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

package school

import "errors"

type Student struct {
 ID    int
 Name  string
 Score int
}

func NewStudent(id int, name string, score int) (*Student, error) {
 if id <= 0 {
  return nil, errors.New("id could not less than 0")
 }

 if score < 0 || score > 100 {
  return nil, errors.New("score must between 0 and 100")
 }

 return &Student{id, name, score}, nil
}

fmt.Errorf()函数

有时候我们需要复杂的错误信息,如果直接调用errors.New()方法的话,需要自己拼接字符串,而标准库fmt包的Errorf()函数可以格式化文本并返回一个error类型:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

package school

import (
 "fmt"
)

type Student struct {
 ID    int
 Name  string
 Score int
}

func NewStudent(id int, name string, score int) (*Student, error) {
 if id <= 0 {
  return nil, fmt.Errorf("%d is less than 0", id)
 }

 if score < 0 || score > 100 {
  return nil, fmt.Errorf("%d is not between 0 and 100", score)
 }

 return &Student{id, name, score}, nil
}

自己实现error接口

上述的两种创建error类型方式,本质上都是其包内部有一个error接口的实现,所以如果我们希望返回更详细的错误类型,方便调用者判断,可以实现自己的错误类型:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

package main

import (
 "fmt"
 "net/http"
)

type ResponseError struct {
 code    int
 message string
}

func (r ResponseError) Error() string {
 return fmt.Sprintf(`{"code":%d,"message":"%s"}`, r.code, r.message)
}

func getUser(id string) (map[string]string, error) {
 if len(id) == 0 {
  return nil, &ResponseError{1, "id不能为空"}
 }
 return map[string]string{"id": id, "name": "测试"}, nil
}

func main() {
 http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
  id := r.FormValue("id")
  user, err := getUser(id)

  if err != nil {
   fmt.Fprint(w, err)
   return
  }
  fmt.Fprint(w, user)
 })
 http.ListenAndServe(":80", nil)
}

小结

error类型是Go语言的内置类型,其本质是一个只有Error()方法的接口,因此只要实现该方法就可以作为error类型使用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/49352.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/49352.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定