рдЧреЛрд▓рдВрдЧ рдХреЗ рдмрд╛рд╣рд░ рдЧреЛрд▓рдВрдЧ рдкрд░реАрдХреНрд╖рдг



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

рднрд╛рдЧ 1. рд╣реИрдВрдбрд▓рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг


рдЬрд╛рдиреЗ рдореЗрдВ, рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ "рдиреЗрдЯ / http" рдореЗрдВ http рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЗрд╕реЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдкреНрд░рдпрд╛рд╕ рдХреЗ рдЙрдард╛ рд╕рдХрддреЗ рд╣реИрдВред рдЦреБрд▓рдиреЗ рд╡рд╛рд▓реЗ рдЕрд╡рд╕рд░ рд╣рдореЗрдВ рдЕрддреНрдпрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░рд╛ рдХреЛрдб 42 рд╡реЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдЧрд╛ред

func userHandler(w http.ResponseWriter, r *http.Request) { var user User userId, err := strconv.Atoi(r.URL.Query().Get("id")) if err != nil { w.Write([]byte( "Error")) return } if userId == 42 { user = User{userId, "Jack", 2} } jsonData, _ := json.Marshal(user) w.Write(jsonData) } type User struct { Id int Name string Rating uint } 

рдпрд╣ рдХреЛрдб рдПрдХ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдИрдбреА рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдФрд░ рд░рд┐рдЯрд░реНрди рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рддрд╛ рд╣реИред рдЕрдм рд╣рдореЗрдВ рдЗрд╕реЗ рдкрд░рдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ ...

рдПрдХ рдЕрджреНрднреБрдд рдмрд╛рдд рд╣реИ "рдиреЗрдЯ / http / рд░рд┐рд╢реНрд╡рддрдЦреЛрд░", рдпрд╣ рдЖрдкрдХреЛ рд╣рдорд╛рд░реЗ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдХреЙрд▓ рдХреЛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдФрд░ рдлрд┐рд░ рдЬрд╡рд╛рдм рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

 r := httptest.NewRequest("GET", "http://127.0.0.1:80/user?id=42", nil) w := httptest.NewRecorder() userHandler(w, r) user := User{} json.Unmarshal(w.Body.Bytes(), &user) if user.Id != 42 { t.Errorf("Invalid user id %d expected %d", user.Id, 42) } 

рднрд╛рдЧ 2. рд╣рдиреА, рд╣рдорд╛рд░реЗ рдпрд╣рд╛рдВ рдПрдХ рдмрд╛рд╣рд░реА рдПрдкреАрдЖрдИ рд╣реИ


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

 func ApiCaller(user *User, url string) error { resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() return updateUser(user, resp.Body) } 

рдЗрд╕реЗ рдкрд░рд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдмрд╛рд╣рд░реА рдПрдкреАрдЖрдИ рдирдХрд▓реА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╡рд┐рдХрд▓реНрдк рд╣реИ:

  ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Header().Set("Access-Control-Allow-Origin", "*") fmt.Fprintln(w, `{ "result": "ok", "data": { "user_id": 1, "rating": 42 } }`) })) defer ts.Close() user := User{id: 1} err := ApiCaller(&user, ts.URL) 

ts.URL рдореЗрдВ рдкреНрд░рд╛рд░реВрдк рдХреА рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реЛрдЧреА `http: //127.0.0.1: 49799`, рдЬреЛ рдПрдкреАрдЖрдИ рдореЙрдХ рд╣реЛрдЧрд╛ рдЬреЛ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмреБрд▓рд╛рдПрдЧрд╛

рднрд╛рдЧ 3. рдЖрдзрд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ


рдПрдХ рд╕рд░рд▓ рддрд░реАрдХрд╛ рд╣реИ: рдЖрдзрд╛рд░ рдХреЗ рд╕рд╛рде рдбреЙрдХ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд▓рд╛рдпрди, рдЬреБрдбрд╝рдирд╛рд░ рдФрд░ рд╣рдорд╛рд░реА рдЙрддреНрдХреГрд╖реНрдЯ рд╕реЗрд╡рд╛ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рд▓реЗрдХрд┐рди рдЪрд▓реЛ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдиреНрдпреВрдирддрдо рдирд┐рд░реНрднрд░рддрд╛ рд╡рд╛рд▓реЗ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рдЖрдзрд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрдкрдХреЛ рдбреНрд░рд╛рдЗрд╡рд░ рдХреЛ рд╕реНрд╡рдпрдВ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░, рдХреЛрдб рдФрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ 100 рдкреГрд╖реНрдареЛрдВ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рддреЗ рд╣реБрдП, рдореИрдВ рдЖрдкрдХреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп github.com/DATA-DOG/go-sqlmock рд▓реЗрдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ
рдЖрдк рдбреЙрдХ рдкрд░ sql.Db рд╕реЗ рдирд┐рдкрдЯ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЗрдП рдереЛрдбрд╝рд╛ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдЙрджрд╛рд╣рд░рдг рд▓реЗрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ - рдЧреЛрд░реНрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдУрдЖрд░рдПрдо рд╣реЛрдЧрд╛ ред

 func DbListener(db *gorm.DB) { user := User{} transaction := db.Begin() transaction.First(&user, 1) transaction.Model(&user).Update("counter", user.Counter+1) transaction.Commit() } 

рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдиреЗ рдХрдо рд╕реЗ рдХрдо рдЖрдкрдХреЛ рдпрд╣ рд╕реЛрдЪрдиреЗ рдХрд╛ рдореМрдХрд╛ рджрд┐рдпрд╛ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рдПред "Mock.ExpectExec" рдореЗрдВ рдЖрдк рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рдХрд╡рд░ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдЪреБрди рд╕рдХрддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдпрд╛рдж рд░рдЦрдиреЗ рд╡рд╛рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЬрд┐рд╕ рдХреНрд░рдо рдореЗрдВ рд╕реЗрдЯ рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИ рд╡рд╣ рдСрд░реНрдбрд░ рдФрд░ рдХреЙрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

 func TestDbListener(t *testing.T) { db, mock, _ := sqlmock.New() defer db.Close() mock.ExpectBegin() result := []string{"id", "name", "counter"} mock.ExpectQuery("SELECT \\* FROM `Users`").WillReturnRows(sqlmock.NewRows(result).AddRow(1, "Jack", 2)) mock.ExpectExec("UPDATE `Users`").WithArgs(3, 1).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() gormDB, _ := gorm.Open("mysql", db) DbListener(gormDB.LogMode(true)) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } 

рдореБрдЭреЗ рдпрд╣рд╛рдВ рдЖрдзрд╛рд░ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХрдИ рдЙрджрд╛рд╣рд░рдг рдорд┐рд▓реЗред

рднрд╛рдЧ 4. рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛


рд╣рдордиреЗ рд╡рд┐рднрд┐рдиреНрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдЕрдкрдирд╛ рд╣рд╛рде рдЖрдЬрдорд╛рдпрд╛ рдФрд░ рд╕рдореЗрдЯ рд▓рд┐рдпрд╛ рдХрд┐ рд╕рдм рдХреБрдЫ рднреАрдЧрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реИред рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИред рдореИрдВ рджреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реБрдЭрд╛рддрд╛ рд╣реВрдВ, рдЧреАрд▓рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реВрдВ рдпрд╛ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред

рд╡рд┐рдХрд▓реНрдк 1 - рд╣рдо рд╕рднреА github.com/spf13/afero рдкрд░ рднреАрдЧрддреЗ рд╣реИрдВ

рдкреЗрд╢реЗрд╡рд░реЛрдВ :
  • рдпрджрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЛ рдХреБрдЫ рднреА рдирдпрд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред (рд▓реЗрдХрд┐рди рддрдм рдЖрдк рдЗрд╕реЗ рдкрдврд╝рдХрд░ рдКрдм рдЪреБрдХреЗ рд╣реИрдВ)
  • рд╡рд░реНрдЪреБрдЕрд▓ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛, рдЬреЛ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдмрд╣реБрдд рддреЗрдЬрд╝ рдХрд░реЗрдЧрд╛ред


рд╡рд┐рдкрдХреНрд╖ :
  • рдореМрдЬреВрджрд╛ рдХреЛрдб рдореЗрдВ рд╕рдВрд╢реЛрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
  • Chmod рд╡рд░реНрдЪреБрдЕрд▓ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рддрдм рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдПрдБ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ "рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рдореБрджреНрджреЛрдВ рдФрд░ рдЕрдиреБрдорддрд┐ рд╕реЗ рдмрдЪреЗрдВ"ред

рдЗрди рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ, рдореИрдВрдиреЗ рддреБрд░рдВрдд 2 рдкрд░реАрдХреНрд╖рдг рдХрд┐рдПред рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, рдореИрдВрдиреЗ рдПрдХ рдЕрдкрдардиреАрдп рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдИ рдФрд░ рдЬрд╛рдБрдЪ рдХреА рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

 func FileRead(path string) error { path = strings.TrimRight(path, "/") + "/" //     files, err := ioutil.ReadDir(path) if err != nil { return fmt.Errorf("cannot read from file, %v", err) } for _, f := range files { deleteFileName := path + f.Name() _, err := ioutil.ReadFile(deleteFileName) if err != nil { return err } err = os.Remove(deleteFileName) //     } return nil } 

Afero.Fs рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдиреНрдпреВрдирддрдо рд╕рдВрд╢реЛрдзрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдореВрд▓ рд░реВрдк рд╕реЗ рдХреЛрдб рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ

 func FileReadAlt(path string, fs afero.Fs) error { path = strings.TrimRight(path, "/") + "/" //     files, err := afero.ReadDir(fs, path) if err != nil { return fmt.Errorf("cannot read from file, %v", err) } for _, f := range files { deleteFileName := path + f.Name() _, err := afero.ReadFile(fs, deleteFileName) if err != nil { return err } err = fs.Remove(deleteFileName) //     } return nil } 

рд▓реЗрдХрд┐рди рд╣рдорд╛рд░рд╛ рдордЬрд╝рд╛ рддрдм рддрдХ рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬрдм рддрдХ рд╣рдо рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛ рд▓реЗрддреЗ рдХрд┐ рдореВрд▓ рдирд┐рд╡рд╛рд╕реА рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдпрд╣ рдХрд┐рддрдирд╛ рддреЗрдЬрд╝ рд╣реИред
рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдорд┐рдирдЯ:

 BenchmarkIoutil 5000 242504 ns/op 7548 B/op 27 allocs/op BenchmarkAferoOs 300000 4259 ns/op 2144 B/op 30 allocs/op BenchmarkAferoMem 300000 4169 ns/op 2144 B/op 30 allocs/op 

рдЗрд╕рд▓рд┐рдП, рдкреБрд╕реНрддрдХрд╛рд▓рдп рдорд╛рдирдХ рдХреЗ рдЖрдЧреЗ рдкрд░рд┐рдорд╛рдг рдХрд╛ рдПрдХ рдХреНрд░рдо рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд░реНрдЪреБрдЕрд▓ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдпрд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрдкрдХреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ рд╣реИред

рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ:

haisum.imtqy.com/2017/09/11/golang-ioutil-readall
matthias-endler.de/2018/go-io-testing

рдЕрдВрддрднрд╛рд╖рдг


рдореБрдЭреЗ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ 100% рдХрд╡рд░реЗрдЬ рдкрд╕рдВрдж рд╣реИ, рд▓реЗрдХрд┐рди рдЧреИрд░-рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдпрд╣ рддреНрд░реБрдЯрд┐ рдХреЗ рдЦрд┐рд▓рд╛рдл рд╕реБрд░рдХреНрд╖рд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, 10 рдЕрд▓рдЧ-рдЕрд▓рдЧ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреА рдХреНрд╖рдорддрд╛ рдирд╣реАрдВред

рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреЛрдб рдХреЛ рд░реЛрдХрдирд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рднрдВрдбрд╛рд░ ред

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


All Articles