diff --git a/part_4/4.1/1.go b/part_4/4.1/1.go new file mode 100644 index 0000000..1c49a7a --- /dev/null +++ b/part_4/4.1/1.go @@ -0,0 +1,11 @@ +import "fmt" + +func main() { + names := []string{ + "Alex", + "Max", + "German", + } + + fmt.Printf("My name is %v", names[3]) +} diff --git a/part_4/4.1/2.go b/part_4/4.1/2.go new file mode 100644 index 0000000..71a6ee2 --- /dev/null +++ b/part_4/4.1/2.go @@ -0,0 +1,32 @@ +package main + +import "fmt" + +type Person struct { + name string + age uint8 +} + +func (p *Person) getName() string { + return p.name +} + +func (p *Person) getAge() uint8 { + return p.age +} + +func (p *Person) incAge() { + p.age++ +} + +func main() { + alex := &Person{ + name: "Alex", + age: 26, + } + fmt.Printf("Person data: %+v\n", alex) + alex.incAge() + fmt.Printf("Person data: %+v\n", alex) + alex = nil + alex.incAge() +} diff --git a/part_4/4.2/1.go b/part_4/4.2/1.go new file mode 100644 index 0000000..7600bb3 --- /dev/null +++ b/part_4/4.2/1.go @@ -0,0 +1,27 @@ +package main + +import "fmt" + +type Person struct { + name string + age uint8 +} + +func (p *Person) incAge() { + p.age++ + if p.age > 30 { + panic(fmt.Sprintf("%s too old!!!", p.name)) + } +} + +func main() { + + alex := &Person{ + name: "Alex", + age: 27, + } + for i := 0; i < 6; i++ { + alex.incAge() + } + fmt.Printf("Person data: %+v\n", alex) +} diff --git a/part_4/4.3/1.go b/part_4/4.3/1.go new file mode 100644 index 0000000..a70cd11 --- /dev/null +++ b/part_4/4.3/1.go @@ -0,0 +1,33 @@ +package main + +import "fmt" + +type Person struct { + name string + age uint8 +} + +func (p *Person) incAge() { + p.age++ + if p.age > 30 { + defer func() { + fmt.Println("Calling defer function") + }() + panic(fmt.Sprintf("%s too old!!!", p.name)) + defer func() { // нет смысла в вызове отложенной функции после паники + fmt.Println("Useless function") + }() + } +} + +func main() { + + alex := &Person{ + name: "Alex", + age: 27, + } + for i := 0; i < 6; i++ { + alex.incAge() + } + fmt.Printf("Person data: %+v\n", alex) +} diff --git a/part_4/4.4/1.go b/part_4/4.4/1.go new file mode 100644 index 0000000..b6b662c --- /dev/null +++ b/part_4/4.4/1.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "log" +) + +type Person struct { + name string + age uint8 +} + +func (p *Person) incAge() { + p.age++ + if p.age > 30 { + defer func() { + if err := recover(); err != nil { + log.Printf("%s has a new life, he (she) is %d years old", p.name, p.age) + } + }() + panic(fmt.Sprintf("%s too old!!!", p.name)) + } +} + +func main() { + + alex := &Person{ + name: "Alex", + age: 27, + } + for i := 0; i < 6; i++ { + alex.incAge() + } + fmt.Printf("Person data: %+v\n", alex) +} diff --git a/part_4/4.4/2.go b/part_4/4.4/2.go new file mode 100644 index 0000000..f273702 --- /dev/null +++ b/part_4/4.4/2.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "log" +) + +type Person struct { + name string + age uint8 +} + +func (p *Person) incAge() { + p.age++ + if p.age > 30 { + defer func() { + if err := recover(); err != nil { + log.Printf("%s has a new life, he (she) is %d years old", p.name, p.age) + if p.age > 35 { + panic(fmt.Sprintf("%s super old!!!", p.name)) + } + } + }() + panic(fmt.Sprintf("%s too old!!!", p.name)) + } +} + +func main() { + + alex := &Person{ + name: "Alex", + age: 27, + } + + defer func() { + if err := recover(); err != nil { + log.Printf("%s, welcome to club: 'А вот в наши времена'", alex.name) + } + }() + for i := 0; i < 20; i++ { + alex.incAge() + } + fmt.Printf("Person data: %+v\n", alex) +} diff --git a/part_4/4.5/1.go b/part_4/4.5/1.go new file mode 100644 index 0000000..f8ba208 --- /dev/null +++ b/part_4/4.5/1.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "strconv" +) + +func main() { + var str string = "10" + value, err := strconv.Atoi(str) // преобразование строки в целочисленное значение + if err != nil { // если err != nil, то обрабатываем ошибку + value = 22 + } + fmt.Println(value) // 10 + + str = "2we" + value, err = strconv.Atoi(str) + if err != nil { // если err != nil, то обрабатываем ошибку + value = 22 + } + fmt.Println(value) // 22 +} diff --git a/part_4/4.5/2.go b/part_4/4.5/2.go new file mode 100644 index 0000000..734ba53 --- /dev/null +++ b/part_4/4.5/2.go @@ -0,0 +1,12 @@ +package main + +import ( + "errors" + "fmt" +) + +func main() { + myError1 := errors.New("first error") + myError2 := fmt.Errorf("second error") + fmt.Println(myError1, myError2) // first error second error +} diff --git a/part_4/4.5/3.go b/part_4/4.5/3.go new file mode 100644 index 0000000..62eda47 --- /dev/null +++ b/part_4/4.5/3.go @@ -0,0 +1,25 @@ +package main + +import "fmt" + +func div(a, b int) (int, error) { + if b == 0 { + return 0, fmt.Errorf("Сan't divide '%v' by zero", a) + } + return a / b, nil +} + +func printResult(result int, err error) { + if err != nil { + fmt.Println(err) + } else { + fmt.Println(result) + } +} + +func main() { + a, b := 10, 2 + printResult(div(a, b)) // 5 + a, b = 4, 0 + printResult(div(a, b)) // Сan't divide '4' by zero +} diff --git a/part_4/4.6/1.go b/part_4/4.6/1.go new file mode 100644 index 0000000..90c8f91 --- /dev/null +++ b/part_4/4.6/1.go @@ -0,0 +1,31 @@ +package main + +import ( + "errors" + "fmt" +) + +// Объявление пользовательского варианта ошибки деления на ноль +var ErrDivByZero = errors.New("divide by zero") + +func div(a, b int) (int, error) { + if b == 0 { + return 0, ErrDivByZero + } + return a / b, nil +} + +func printResult(result int, err error) { + if err != nil { + fmt.Println(err) + } else { + fmt.Println(result) + } +} + +func main() { + a, b := 10, 2 + printResult(div(a, b)) // 5 + a, b = 4, 0 + printResult(div(a, b)) // divide by zero +} diff --git a/part_4/4.7/1.go b/part_4/4.7/1.go new file mode 100644 index 0000000..95e616c --- /dev/null +++ b/part_4/4.7/1.go @@ -0,0 +1,41 @@ +package main + +import ( + "errors" + "fmt" +) + +var ErrDivByZero = errors.New("divide by zero") +var ErrDivByOne = errors.New("divide by one") + +func div(a, b int) (int, error) { + if b == 0 { + return 0, ErrDivByZero + } + if b == 1 { + return a, ErrDivByOne + } + return a / b, nil +} + +func printResult(result int, err error) { + if err != nil { + switch { + case errors.Is(err, ErrDivByZero): + fmt.Println(err) + case errors.Is(err, ErrDivByOne): + fmt.Printf("result = %d, but was %v\n", result, err) + default: + fmt.Printf("unexpected error: %v\n", err) + } + + } else { + fmt.Println(result) + } +} + +func main() { + printResult(div(10, 2)) // 5 + printResult(div(4, 0)) // divide by zero + printResult(div(12, 1)) // result = 12, but was divide by one +} diff --git a/part_4/4.8/1.go b/part_4/4.8/1.go new file mode 100644 index 0000000..0c231e8 --- /dev/null +++ b/part_4/4.8/1.go @@ -0,0 +1,62 @@ +package main + +import ( + "errors" + "fmt" +) + +type DivError struct { + Numerator int + Denominator int + Msg string +} + +func (d *DivError) Error() string { + return d.Msg +} + +func div(a, b int) (int, error) { + if b == 0 { + return 0, &DivError{ + Numerator: a, + Denominator: b, + Msg: fmt.Sprintf("Сan't divide '%v' by zero", a), + } + } + if b == 1 { + return a, &DivError{ + Numerator: a, + Denominator: b, + Msg: "Divide by one", + } + } + return a / b, nil +} + +func printResult(result int, err error) { + if err != nil { + var myDivError *DivError + switch { + case errors.As(err, &myDivError): + fmt.Printf("Numerator: %d, Denominator: %d, Error: %s\n", + myDivError.Numerator, myDivError.Denominator, myDivError.Msg) + if myDivError.Denominator == 1 { + fmt.Printf("result = %d, but was %v\n", + myDivError.Numerator, myDivError.Msg) + } + default: + fmt.Printf("unexpected error: %v\n", err) + } + + } else { + fmt.Println(result) + } +} + +func main() { + printResult(div(10, 2)) // 5 + printResult(div(4, 0)) // Numerator: 4, Denominator: 0, Error: Сan't divide '4' by zero + printResult(div(12, 1)) + // Numerator: 12, Denominator: 1, Error: Divide by one + // result = 12, but was divide by one +} diff --git a/part_4/4.9/1.go b/part_4/4.9/1.go new file mode 100644 index 0000000..dd77ecf --- /dev/null +++ b/part_4/4.9/1.go @@ -0,0 +1,122 @@ +package main + +import ( + "errors" + "fmt" +) + +type User struct { + ID uint + Name string + Age uint8 +} + +type UserDB struct { + users []User +} + +func (db *UserDB) FindUserWithID(id uint) (*User, error) { + for _, it := range db.users { + if it.ID == id { + return &it, nil + } + } + return nil, fmt.Errorf("User with id=%v not found", id) +} + +func (db *UserDB) SetUserAge(id uint, age uint8) error { + for _, it := range db.users { + if it.ID == id { + it.Age = age + return nil + } + } + return fmt.Errorf("User with id=%v not found", id) +} + +func (db *UserDB) AddUser(user User) error { + for _, it := range db.users { + if it.ID == user.ID { + return fmt.Errorf("User with id=%v already exist", user.ID) + } + } + db.users = append(db.users, user) + return nil +} + +func (db *UserDB) DeleteUserWithName(name string) error { + index := -1 + for idx, it := range db.users { + if it.Name == name { + index = idx + break + } + } + if index < 0 { + return fmt.Errorf("User %s not found", name) + } + db.users = append(db.users[:index], db.users[index+1:]...) + return nil +} + +// функции для работы с БД и организации цепочек ошибок +func findUserWithID(db *UserDB, id uint) (*User, error) { + user, err := db.FindUserWithID(id) + if err != nil { + // вернется ошибка из 2-х вложений + return nil, fmt.Errorf("DataBase error: %w", err) + } + return user, nil +} + +func setUserAge(db *UserDB, id uint, age uint8) error { + err := db.SetUserAge(id, age) + if err != nil { + // вернется ошибка из 2-х вложений + return fmt.Errorf("DataBase user data error: %w", err) + } + return nil +} + +func addUser(db *UserDB, user User) error { + err := db.AddUser(user) + if err != nil { + // вернется ошибка из 2-х вложений + return fmt.Errorf("Add user error: %w", err) + } + return nil +} + +func main() { + dbUsers := UserDB{ + []User{ + {2, "Alex", 28}, + {1, "Max", 23}, + {10, "German", 35}, + {6, "Oleg", 19}, + }, + } + + user, err := findUserWithID(&dbUsers, 2) + if err != nil { + fmt.Println(err) + // распаковка трассировки ошибок + fmt.Println(errors.Unwrap(err)) + } + fmt.Printf("%+v\n", user) // &{ID:2 Name:Alex Age:28} + + user, err = findUserWithID(&dbUsers, 12) + if err != nil { + fmt.Println(err) // DataBase error: User with id=12 not found + // распаковка трассировки ошибок + fmt.Println(errors.Unwrap(err)) // User with id=12 not found + } + fmt.Printf("%+v\n", user) // + + newErr := addUser(&dbUsers, User{6, "Li", 45}) + if newErr != nil { + fmt.Println(newErr) // Add user error: User with id=6 already exist + // распаковка трассировки ошибок + fmt.Println(errors.Unwrap(newErr)) // User with id=6 already exist + } +}