package main
import (
    "errors"
    "fmt"
)
var ErrDidNotWork = errors.New("did not work")
func DoTheThing(reallyDoIt bool) (err error) {
    if reallyDoIt {
        result, err := tryTheThing()
        if err != nil || result != "it worked" {
            err = ErrDidNotWork
        }
    }
    return err
}
func tryTheThing() (string,error)  {
    return "",ErrDidNotWork
}
func main() {
    fmt.Println(DoTheThing(true))
    fmt.Println(DoTheThing(false))
}
|  |      1NicolayShi OP 有说因为 if 语句块内的 err 变量会遮罩函数作用域内的 err 变量,但是没看懂。 | 
|      2slicent8      2019-04-19 16:36:29 +08:00 package main import ( "errors" "fmt" ) var ErrDidNotWork = errors.New("did not work") func DoTheThing(reallyDoIt bool) (err error) { if reallyDoIt { result, err1 := tryTheThing() if err1 != nil || result != "it worked" { err = ErrDidNotWork } } return err } func tryTheThing() (string,error) { return "",ErrDidNotWork } func main() { fmt.Println(DoTheThing(true)) fmt.Println(DoTheThing(false)) } | 
|      3thuai      2019-04-19 16:39:10 +08:00 DoTheThing 的返回值带了名字与 if 语句中的 err:= 冲突了,命名返回值是相当于声明了 err 变量,err := 又做了一次 | 
|      4fighterlyt      2019-04-19 16:39:44 +08:00 确实是因为        result, err := tryTheThing()中的 err 屏蔽了外层的 err,所以外层 err 没有变化 | 
|      5Junjunya      2019-04-19 16:40:54 +08:00 err  在 if 里面重新被声明并且赋值了,属于局部变量 。 而 rerturn 的 err 是在 在 return_types 位置声明的。 并且 一直没有赋值,所以一直都是 nil | 
|      6Heavytiger      2019-04-19 16:41:52 +08:00 (err error) err = nil 因为这个。 | 
|  |      7qq316107934      2019-04-19 16:45:25 +08:00 @NicolayShi #1 | 
|  |      8qq316107934      2019-04-19 16:46:55 +08:00 ``` package main import ( "fmt" "errors" ) func main() { DoTheThing(true) } func DoTheThing(reallyDoIt bool) (err error) { err = errors.New("Custom Error 0") fmt.Println(err) if reallyDoIt { err := errors.New("Custom Error 1") fmt.Println(err) if err != nil { err := errors.New("Custom Error 2") fmt.Println(err) } fmt.Println(err) } fmt.Println(err) return err } ``` 跑下这个有助于你理解 @NicolayShi #1 | 
|  |      9qq316107934      2019-04-19 16:47:25 +08:00 顺便问句这个为啥在 PHP 节点 | 
|      10dust09      2019-04-19 16:51:03 +08:00 DoTheThing 函数内 err 不是同一个 ````go package main import ( "errors" "fmt" ) var ErrDidNotWork = errors.New("did not work") func DoTheThing(reallyDoIt bool) (err error) { fmt.Println("err:",&err) if reallyDoIt { result, err := tryTheThing() if err != nil || result != "it worked" { err = ErrDidNotWork } fmt.Println("err:",&err) } return err } func tryTheThing() (string,error) { return "",ErrDidNotWork } func main() { fmt.Println(DoTheThing(true)) fmt.Println(DoTheThing(false)) } ```` | 
|  |      11NicolayShi OP 十分感谢大家,在此统一回复,因为没找到 golang 节点自己工作又是写 php,所以就在 php 节点提问了,所以我是没搞清楚 golang 的变量作用域是么(掩面哭泣 emoj )~ | 
|  |      12janxin      2019-04-19 17:47:54 +08:00 @NicolayShi 是的,如果你使用 GoLand 之类的 IDE,会有波浪线提醒你这里使用有问题的,不如考虑一下? | 
|      13johz      2019-04-19 17:55:07 +08:00 是作用域问题,:=赋值之后 err 变量覆盖了 这样就好了: package main import ( "errors" "fmt" ) var ErrDidNotWork = errors.New("did not work") func DoTheThing(reallyDoIt bool) (err error) { if reallyDoIt { result, err2 := tryTheThing() if err2 != nil || result != "it worked" { err = ErrDidNotWork } } return err } func tryTheThing() (string,error) { return "",ErrDidNotWork } func main() { fmt.Println(DoTheThing(true)) fmt.Println(DoTheThing(false)) } 自己体会一下~ | 
|      14Mitt      2019-04-19 20:07:05 +08:00 via iPhone := 这个语法很坑爹我觉得,很多时候图一下方便就容易踩坑 | 
|  |      15unlimitedsola      2019-04-20 04:02:31 +08:00 改成这样也是可以的 ```go package main import ( "errors" "fmt" ) var ErrDidNotWork = errors.New("did not work") func DoTheThing(reallyDoIt bool) (err error) { result := "" if reallyDoIt { result, err = tryTheThing() if err != nil || result != "it worked" { err = ErrDidNotWork } } return err } func tryTheThing() (string, error) { return "", ErrDidNotWork } func main() { fmt.Println(DoTheThing(true)) fmt.Println(DoTheThing(false)) } ``` |