mirror of
https://github.com/MADTeacher/go_basics.git
synced 2025-11-23 21:34:47 +02:00
отредактирована 4-я глава
This commit is contained in:
11
part_4/4.1/1.go
Normal file
11
part_4/4.1/1.go
Normal 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
32
part_4/4.1/2.go
Normal 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
27
part_4/4.2/1.go
Normal 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
33
part_4/4.3/1.go
Normal 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
35
part_4/4.4/1.go
Normal 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
44
part_4/4.4/2.go
Normal 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
22
part_4/4.5/1.go
Normal 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
12
part_4/4.5/2.go
Normal 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
25
part_4/4.5/3.go
Normal 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
31
part_4/4.6/1.go
Normal 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
41
part_4/4.7/1.go
Normal 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
62
part_4/4.8/1.go
Normal 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
122
part_4/4.9/1.go
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user