为了账号安全,请及时绑定邮箱和手机立即绑定

为什么接受自定义结构来代替错误?

为什么接受自定义结构来代替错误?

Go
慕沐林林 2022-04-26 10:52:56
学习 Go 并参考https://tour.golang.org/methods/20package mainimport (    "fmt"    "math")type ErrNegativeSqrt float64 //This is the custom Structfunc (e ErrNegativeSqrt) Error() string {     return fmt.Sprintf("cannot Sqrt negative number: %g", float64(e))}func Sqrt(x float64) (float64, error) {  // Is error a type ?    if(x < 0){        return x, ErrNegativeSqrt(x) //Q1) If error is a type, How come  ErrNegativeSqrt(x) is of type error?    }           z := float64(1.5)    val := float64(0)    for {        z = z - (z*z-x)/(2*z)        if math.Abs(val-z) < 1e-10 {            break        }        val = z    }    return val, nil}func main() {    fmt.Println(Sqrt(2))    fmt.Println(Sqrt(-2))}Q2) 为什么在 Error 方法中调用 fmt.Sprint(e) 会使程序陷入无限循环?
查看完整描述

2 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

围棋interface很棘手。需要对它进行一些试验才能很好地了解如何使用它。这就是为什么您正在使用的教程让您使用它编写东西:您必须实际使用它一段时间才能了解如何使用它。:-)


不过,值得在这里纠正一些细节:


type ErrNegativeSqrt float64 //This is the custom Struct

这不是一个struct类型。 float64本身是一个预先声明的数字类型,如 Go 参考中所定义:


数字类型表示整数或浮点值的集合。预先声明的独立于体系结构的数字类型是:[这里剪掉的各种条目]


float64     the set of all IEEE-754 64-bit floating-point numbers

您type在此处的声明创建了一个名为的新类型ErrNegativeSqrt,float64它的基础类型为;请参阅类型部分。


一个类型——任何类型,无论是否struct——要么实现接口类型,要么不实现。接口类型很复杂。完整图片请参见接口类型部分。Goerror是一个预先声明的接口类型,由Errors部分定义:


预先声明的类型error定义为


type error interface {

    Error() string

}

这意味着每当您定义自己的类型UserT时,如果您添加如下一行:


func (varname UserT) Error() string {

    // return some string here

}

您定义的类型UserT现在实现了错误接口。因此,您可以通过简单的赋值将UserT类型的任何值转换为。请参阅可分配性部分,其中包括:error


如果以下条件之一适用,则可以将值分配给类型为 ... 的变量:[一些子弹x项目被剪断]T


T是一个接口类型并x实现T

我们刚刚看到这error是一个接口类型。因此,如果某些情况需要 type 的变量error,并且您有一些现有x的 type值,UserT其中UserT有一个方法Error() string,则可以将该值分配给xtype 的变量error。也就是说,ErrNegativeSqrt按照您所做的设置,并且:


var x ErrNegativeSqrt

// set `x` to some valid value


// and:

var e error

然后:


e = x

是有效的并赋值给x,e尽管它本身的类型是接口类型,而不是.eErrNegativeSqrt


当您像这样将 的值的副本x 塞入 其中e时,编译器实际上会在. 换句话说,它的行为很像一个二元素数组,或者一个包含两个字段的数组,只是您不能使用下标或类型拼写访问这两个字段。eestruct.field


这两个值之一—— e' 值的前半部分——是x'具体类型。这两个值中的另一个是x的实际值,复制到 的另一半e。


换句话说,编译器转向:


e = x

大致相当于:


e.value = x

e.type = ErrNegativeSqrt

再次,除了你实际上不能写 e.typeand的事实e.value。编译器会自动为您进行两部分化。


您应该已经了解了如何e在必要时将存储的东西的两部分分开。 通常没有必要,尤其是在界面设计良好的情况下。但是在尝试了#20中的错误返回之后,值得回溯到巡回赛的这些早期部分。


查看完整回答
反对 回复 2022-04-26
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

错误是定义Error() string方法的接口。如果您的错误实现了该接口,那很好。


func (e ErrNegativeSqrt) Error() string { 

    return fmt.Sprintf("cannot Sqrt negative number: %g", float64(e))

}

而那个代码正是这样做的。现在你的ErrNegativeSqrt类型实现了错误接口。


if(x < 0){

        return x, ErrNegativeSqrt(x) // totally fine.

    }


查看完整回答
反对 回复 2022-04-26
  • 2 回答
  • 0 关注
  • 210 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号