1
0
mirror of https://github.com/MADTeacher/go_basics.git synced 2025-11-23 21:34:47 +02:00

отредактирована 4-я глава

This commit is contained in:
Stanislav Chernyshev
2025-06-04 19:37:39 +03:00
parent f97178b439
commit 17e17055d4
13 changed files with 497 additions and 0 deletions

11
part_4/4.1/1.go Normal file
View File

@@ -0,0 +1,11 @@
import "fmt"
func main() {
names := []string{
"Alex",
"Max",
"German",
}
fmt.Printf("My name is %v", names[3])
}

32
part_4/4.1/2.go Normal file
View File

@@ -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()
}

27
part_4/4.2/1.go Normal file
View File

@@ -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)
}

33
part_4/4.3/1.go Normal file
View File

@@ -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)
}

35
part_4/4.4/1.go Normal file
View File

@@ -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)
}

44
part_4/4.4/2.go Normal file
View File

@@ -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)
}

22
part_4/4.5/1.go Normal file
View File

@@ -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
}

12
part_4/4.5/2.go Normal file
View File

@@ -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
}

25
part_4/4.5/3.go Normal file
View File

@@ -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
}

31
part_4/4.6/1.go Normal file
View File

@@ -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
}

41
part_4/4.7/1.go Normal file
View File

@@ -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
}

62
part_4/4.8/1.go Normal file
View File

@@ -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
}

122
part_4/4.9/1.go Normal file
View File

@@ -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) // <nil>
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
}
}