Go 2 рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ

рд╢реАрд░реНрд╖рдХ


рдбреЗрдирд╡рд░ рдореЗрдВ рдЕрднреА рдХреБрдЫ рджрд┐рди рдкрд╣рд▓реЗ, рдЕрдЧрд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 5, рдЧреЛ - рдЧреЛрдлрд░рдХреЙрди рдкрд░ рд╕рдмрд╕реЗ рдмрдбрд╝рд╛ рд╕рдореНрдореЗрд▓рди рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ ред рдЗрд╕ рдкрд░, рдЧреЛ рдЯреАрдо рдиреЗ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрдпрд╛рди рджрд┐рдпрд╛ - рдЧреЛ 2 рдореЗрдВ рдирдИ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдФрд░ рдЬреЗрдирд░рд┐рдХ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдбрд┐рдЬрд╛рдЗрди рдХреЗ рдбреНрд░рд╛рдлреНрдЯ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рд╕рднреА рдХреЛ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рдЖрдордВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдореИрдВ рддреАрди рдЖрд▓реЗрдЦреЛрдВ рдореЗрдВ рдЗрди рдорд╕реМрджреЛрдВ рдХреЗ рд╕рд╛рд░ рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред


рдЬреИрд╕рд╛ рдХрд┐ рдХрдИ рд▓реЛрдЧ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдкрд┐рдЫрд▓реЗ рд╕рд╛рд▓ (рдЧреЛрдлрд░рдХреЙрди рдореЗрдВ рднреА), рдЧреЛ рдЯреАрдо рдиреЗ рдШреЛрд╖рдгрд╛ рдХреА рдХрд┐ рд╡рд╣ рдЧреЛ рдХреА рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд┐рдкреЛрд░реНрдЯ ( рдЕрдиреБрднрд╡ рд░рд┐рдкреЛрд░реНрдЯ ) рдФрд░ рд╕реБрдЭрд╛рд╡ рдПрдХрддреНрд░ рдХрд░ рд░рд╣реА рдереА - рдЙрди рдмрд┐рдВрджреБрдУрдВ рдХреА, рдЬрд┐рдирдХреА рдЪреБрдирд╛рд╡реЛрдВ рдореЗрдВ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЖрд▓реЛрдЪрдирд╛ рд╣реБрдИ рдереАред рд╡рд░реНрд╖ рдХреЗ рджреМрд░рд╛рди, рд╕рднреА рдкреНрд░рд╕реНрддрд╛рд╡реЛрдВ рдФрд░ рд░рд┐рдкреЛрд░реНрдЯреЛрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдФрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдорд╕реМрджрд╛ рдбрд┐рдЬрд╛рдЗрди рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХреА рдЧрдИ рдереА, рдЬрд┐рд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред


рддреЛ, рдЪрд▓реЛ рдирдП рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рддрдВрддреНрд░ рдХреЗ рдбреНрд░рд╛рдлреНрдЯ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред


рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЫреЛрдЯрд╛ рд╡рд┐рд╖рдпрд╛рдВрддрд░:


  1. рдЧреЛ 2 рдПрдХ рд╕рд╢рд░реНрдд рдирд╛рдо рд╣реИ - рд╕рднреА рдирд╡рд╛рдЪрд╛рд░ рдЧреЛ рд╕рдВрд╕реНрдХрд░рдг рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреА рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реЛрдВрдЧреЗред рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЕрднреА рднреА рдЕрдЬреНрдЮрд╛рдд рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдЧреЛ 1.34 рдпрд╛ рдЧреЛ 2 рд╣реЛрдЧрд╛ред рдЕрдЬрдЧрд░ 2/3 рд▓рд┐рдкрд┐ рдХрд╛ рд▓реЛрд╣рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
  2. рдбрд┐рдЬрд╛рдЗрди рдХреЗ рдбреНрд░рд╛рдлреНрдЯ рднреА рдкреНрд░рд╕реНрддрд╛рд╡ рдирд╣реАрдВ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдкреБрд╕реНрддрдХрд╛рд▓рдп, рдЯреНрдпреВрдирд┐рдВрдЧ рдпрд╛ рдЧреЛ рднрд╛рд╖рд╛ рдореЗрдВ рдХреЛрдИ рднреА рдмрджрд▓рд╛рд╡ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдЗрди рдореБрджреНрджреЛрдВ рдкрд░ рдХрдИ рд╡рд░реНрд╖реЛрдВ рдХреЗ рдХрд╛рдо рдХреЗ рдмрд╛рдж рдЧреЛ рдЯреАрдо рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдбрд┐рдЬрд╛рдЗрди рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╢реБрд░реБрдЖрддреА рдмрд┐рдВрджреБ рд╣реИред рдЙрдЪреНрдЪ рдХреНрд╖рдорддрд╛ рд╡рд╛рд▓реЗ рдбреНрд░рд╛рдлреНрдЯ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╕рднреА рдЪреАрдЬреЛрдВ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░, рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреЗ рдкрд░рд┐рджреГрд╢реНрдп рдореЗрдВ, рдХреБрдЫ рд░рд┐рд▓реАрдЬ рдХреЗ рдмрд╛рдж рд╣реА рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рдмрди рдЬрд╛рдПрдЧреА (рдореИрдВ ~ 2 рд╕рд╛рд▓ рджреЗрддрд╛ рд╣реВрдВ)ред

Go рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдореЗрдВ рдХреНрдпрд╛ рд╕рдорд╕реНрдпрд╛ рд╣реИ?


рдЧреЛ рдиреЗ рд╢реБрд░реВ рдореЗрдВ "рд╕реНрдкрд╖реНрдЯ" рддреНрд░реБрдЯрд┐ рдЬрд╛рдБрдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд▓реЛрдХрдкреНрд░рд┐рдп "рдирд┐рд╣рд┐рдд" рдЬрд╛рдБрдЪ рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реИ - рдЕрдкрд╡рд╛рджред рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рддреНрд░реБрдЯрд┐ рдЬрд╛рдБрдЪ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ "рдХреНрд▓реАрдирд░, рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдФрд░ рдЕрдзрд┐рдХ рд╕рд╣реА рдирд╣реАрдВ" рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрд┐рдд рд╣реИ, рдЬреЛ рдХрд┐ рдХреБрдЫ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рдордЭрдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реИред


рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╛рд▓реНрдкрдирд┐рдХ рдЧреЛ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рд▓реЗрдВ:


func CopyFile(src, dst string) throws error {
    r := os.Open(src)
    defer r.Close()

    w := os.Create(dst)
    io.Copy(w, r)
    w.Close()
}

, . : io.Copy w.Close , .


, Go :


func CopyFile(src, dst string) error {
    r, err := os.Open(src)
    if err != nil {
        return err
    }
    defer r.Close()

    w, err := os.Create(dst)
    if err != nil {
        return err
    }
    defer w.Close()

    if _, err := io.Copy(w, r); err != nil {
        return err
    }
    if err := w.Close(); err != nil {
        return err
    }
}

, , , тАУ  . , , тАУ " ", - , , , .


, ( , , ..) , .


, Go . :


func CopyFile(src, dst string) error {
    r, err := os.Open(src)
    if err != nil {
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }
    defer r.Close()

    w, err := os.Create(dst)
    if err != nil {
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }

    if _, err := io.Copy(w, r); err != nil {
        w.Close()
        os.Remove(dst)
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }

    if err := w.Close(); err != nil {
        os.Remove(dst)
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }
}

, .



Go Go 2:


  • , ,
  • , ,
  • тАУ  ,
  • Go ,

Go.



.


  • check(x,y,z) check err
  • handle тАУ ,

check , handle ( handler, , . , return)


:


func CopyFile(src, dst string) error {
    handle err {
        return fmt.Errorf("copy %s %s: %v", src, dst, err)
    }

    r := check os.Open(src)
    defer r.Close()

    w := check os.Create(dst)
    handle err {
        w.Close()
        os.Remove(dst) // (  check )
    }

    check io.Copy(w, r)
    check w.Close()
    return nil
}

, ( main). :


func main() {
    hex, err := ioutil.ReadAll(os.Stdin)
    if err != nil {
        log.Fatal(err)
    }

    data, err := parseHexdump(string(hex))
    if err != nil {
        log.Fatal(err)
    }

    os.Stdout.Write(data)
}

:


func main() {
    handle err {
        log.Fatal(err)
    }

    hex := check ioutil.ReadAll(os.Stdin)
    data := check parseHexdump(string(hex))
    os.Stdout.Write(data)
}

, . :


func printSum(a, b string) error {
    x, err := strconv.Atoi(a)
    if err != nil {
        return err
    }
    y, err := strconv.Atoi(b)
    if err != nil {
        return err
    }
    fmt.Println("result:", x + y)
    return nil
}

:


func printSum(a, b string) error {
    handle err { return err }
    x := check strconv.Atoi(a)
    y := check strconv.Atoi(b)
    fmt.Println("result:", x + y)
    return nil
}

:


func printSum(a, b string) error {
    handle err { return err }
    fmt.Println("result:", check strconv.Atoi(x) + check strconv.Atoi(y))
    return nil
}

check handle.


Check


check ( ) , "" error, , . nil, check (handler), return .


:


v1, ..., vN := check <>

:


v1, ..., vN, vErr := <>
if vErr != nil {
    <error result> = handlerChain(vn)
    return
}

vErr error <error result> , .


,


foo(check <>)

:


v1, ..., vN, vErr := <>
if vErr != nil {
    <error result> = handlerChain(vn)
    return
}
foo(v1, ..., vN)

Check try


try check тАУ /, , , Rust Swift try ( Rust ? ).


try :


data := try parseHexdump(string(hex))

:


data, err := parseHexdump(string(hex))
if err == ErrBadHex {
    ... special handling ...
}
try err

, try c . check/handle , check .


Handle


handle , "" (handler), , check. (return) . ( , return) ( func foo() (bar int, err error)).


, " " тАУ , , , error , , . :


func handler(err error) error {...}

( , , тАУ  ).



тАУ  , . (check) , , . , , тАУ  . :


func process(user string, files chan string) (n int, err error) {
    handle err { return 0, fmt.Errorf("process: %v", err)  }      // handler A
    for i := 0; i < 3; i++ {
        handle err { err = fmt.Errorf("attempt %d: %v", i, err) } // handler B
        handle err { err = moreWrapping(err) }                    // handler C

        check do(something())  // check 1: handler chain C, B, A
    }
    check do(somethingElse())  // check 2: handler chain A
}

check 1 C, B A тАУ . check 2 A, C B for-.


, . if , (handle) ( ) , тАУ , , :


type Error struct {
    Func string
    User string
    Path string
    Err  error
}

func (e *Error) Error() string

func ProcessFiles(user string, files chan string) error {
    e := Error{ Func: "ProcessFile", User: user}
    handle err { e.Err = err; return &e } // handler A
    u := check OpenUserInfo(user)         // check 1
    defer u.Close()
    for file := range files {
        handle err { e.Path = file }       // handler B
        check process(check os.Open(file)) // check 2
    }
    ...
}

, handle defer, , , . тАУ , . , handler B тАУ  defer , . Go defer/panic handle/check , , -.


тАУ (.. return), - . .


(panic) , .


-


тАУ (handle err {}). " -" (default handler). handle , , -, , check ( ; тАФ zero values).


-:


func printSum(a, b string) error {
    x := check strconv.Atoi(a)
    y := check strconv.Atoi(b)
    fmt.Println("result:", x + y)
    return nil
}


Go , . - , , . , t.Helper() , :


func TestFoo(t *testing.T) {
    handle err {
        t.Helper()
        t.Fatal(err)
    }
    for _, tc := range testCases {
        x := check Foo(tc.a)
        y := check Foo(tc.b)
        if x != y {
            t.Errorf("Foo(%v) != Foo(%v)", tc.a, tc.b)
        }
    }
}

(shadowing)


check (:=), err. handle/check .



defer/panic


(defer/panic handle/check) . .


handle defer (, , , ), handle/check defer-. :


func Greet(w io.WriteCloser) error {
    defer func() {
        check w.Close()
    }()
    fmt.Fprintf(w, "hello, world\n")
    return nil
}

, .



Go тАУ  , . - "", , defer, break goto. , goto, , .



try, catch, ? , . , Go , check handle .


, handle catch , ( , (keywords) ).



Go2?


. Go, 2-3 , тАУ . , 2-3 .


, , Go2 тАУ  . , Go тАУ Go 1.20 . .


, ?


. / . , , , Go.


Go 2 тАУ , if err != nil {} , handle/check?


, , if err , тАУ  , . , .


?  , Go .


. , .


?


, , . , - . , , , , .


, ! ?


- Go2ErrorHandlingFeedback



  • Go тАФ  handle/check
  • -
  • , ,
  • / ( defer/panic)



? ?


Source: https://habr.com/ru/post/hi422049/


All Articles