Go: инструментарий (продолжение)

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Go: инструментарий (продолжение)

Непрочитанное сообщение Olej » 10 фев 2024, 02:59

Olej писал(а):
10 фев 2024, 02:57
Но чтобы продемонстрировать ошибку мне нужно вернуться к предыдущей версии Go...
Это само по себе крайне просто...
Было:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go version
go version go1.22.0 linux/amd64

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ sudo update-alternatives --config go
[sudo] пароль для olej:
Есть 3 варианта для альтернативы go (предоставляет /usr/bin/go).

  Выбор   Путь              Приор Состояние
------------------------------------------------------------
* 0            /usr/local/go/bin/go   85        автоматический режим
  1            /lib/go-1.13/bin/go    60        ручной режим
  2            /lib/go-1.18/bin/go    75        ручной режим
  3            /usr/local/go/bin/go   85        ручной режим

Нажмите «enter», чтобы не менять текущий выбор[*], или введите нужное число: 2
update-alternatives: используется /lib/go-1.18/bin/go для предоставления /usr/bin/go (go) в ручном режиме
Стало:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ go version
go version go1.18.1 linux/amd64

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Go: инструментарий (продолжение)

Непрочитанное сообщение Olej » 10 фев 2024, 03:05

Olej писал(а):
10 фев 2024, 02:59
Это само по себе крайне просто...
Но вот

Код: Выделить всё

импорт
и описание модуля mod.go - у нас всё готовилось для предыдущей версии :!:
И все попытки "на ходу" поменять mod.go - не венчаются успехом: :cry:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ go build errgrp.go
# golang.org/x/sync/errgroup
/home/olej/go/pkg/mod/golang.org/x/sync@v0.6.0/errgroup/go120.go:12:9: undefined: context.WithCancelCause
/home/olej/go/pkg/mod/golang.org/x/sync@v0.6.0/errgroup/pre_go120.go:11:6: withCancelCause redeclared in this block
    previous declaration at /home/olej/go/pkg/mod/golang.org/x/sync@v0.6.0/errgroup/go120.go:11:69
note: module requires Go 1.18

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ go mod tidy
go: errors parsing go.mod:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ go mod init new.vers
go: /home/olej/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp/go.mod already exists
Мне не хочется лезть в глубину природы ошибок ... но ошибки тяжелейшие :!:
Я знаю только один способ: удалить (или переименовать) mod.go + пересоздать его от начала под новую версию :!:

Код: Выделить всё

lej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ mv go.mod go.mod.22

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ go mod init new.vers
go: creating new go.mod: module new.vers
go: to add module requirements and sums:
    go mod tidy

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ go mod tidy
go: finding module for package golang.org/x/sync/errgroup
go: finding module for package github.com/eiannone/keyboard
go: found github.com/eiannone/keyboard in github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203
go: found golang.org/x/sync/errgroup in golang.org/x/sync v0.6.0

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ cat go.mod
module new.vers

go 1.18

require (
    github.com/go-board/std v0.6.0
    golang.org/x/sync v0.6.0
)

require github.com/tidwall/btree v1.7.0 // indirect

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/goproc/errgrp$ go build errgrp.go
Вот теперь всё играет в старой версии 1.18 :lol:

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Go: инструментарий (продолжение)

Непрочитанное сообщение Olej » 10 фев 2024, 03:09

Olej писал(а):
10 фев 2024, 03:05
Вот теперь всё играет в старой версии 1.18
Вот 1-й тестовый файл - forgo1.go:

Код: Выделить всё

package main
import (
	"fmt"
	"context"
	"time"
	"golang.org/x/sync/errgroup"
)

func main() {
	ctx, _ := context.WithCancel(context.Background())
	gr, _ := errgroup.WithContext(ctx)
	for i := 0; i < 4; i++ {
//		i := i
		gr.Go( func() error {
			t0 := time.Now()
			defer func() {
				fmt.Printf("%d : длительность %v\n", 
							  i, time.Now().Sub(t0))	
			}()

			time.Sleep(300 * time.Millisecond)				
			return nil
		})
	}
	_ = gr.Wait() // Wait for all routines
}
Здесь создаётся группа параллельных горутин (4 шт.), которые каждая выполняется 0.3 сек. и в заключение показывает свой номер i:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go run forgo1.go
4 : длительность 300.679059ms
4 : длительность 300.514798ms
4 : длительность 300.650147ms
4 : длительность 300.752102ms

А вот болт вам :!:
Ко времени выполнения defer индекс i уде пробежал все значения и стал 4.
Вложения
forgo1.go
(483 байт) 9 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Go: инструментарий (продолжение)

Непрочитанное сообщение Olej » 10 фев 2024, 03:21

Olej писал(а):
10 фев 2024, 03:09
А вот болт вам
Этого рода ошибки насколько хорошо известны, настолько же хорошо известно лечатся :!:
Исправленный вариант - forgo2.go

Код: Выделить всё

package main
import (
	"fmt"
	"context"
	"time"
	"golang.org/x/sync/errgroup"
)

func main() {
	ctx, _ := context.WithCancel(context.Background())
	gr, _ := errgroup.WithContext(ctx)
	for i := 0; i < 4; i++ {
		i := i
		gr.Go( func() error {
			t0 := time.Now()
			defer func() {
				fmt.Printf("%d : длительность %v\n", 
							  i, time.Now().Sub(t0))	
			}()

			time.Sleep(300 * time.Millisecond)				
			return nil
		})
	}
	_ = gr.Wait() // Wait for all routines
}
В чём отличие :?:
Отличие в 1-й строке, вот та "странная" строка после цикла for:

Код: Выделить всё

	for i := 0; i < 4; i++ {
		i := i

Эта же строка оставлена закомментированной в 1-м варианте:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ diff forgo1.go forgo2.go
13c13
< //            i := i
---
>               i := i
Вот и всё различие :!:
Но i в строке for и i в следующей строке - это разные переменные, на что указывает := что это определение а не присвоение (где было бы =).
И вот теперь:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go run forgo2.go
3 : длительность 300.515948ms
0 : длительность 300.445678ms
1 : длительность 300.520328ms
2 : длительность 300.466568ms

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go run forgo2.go
0 : длительность 300.568822ms
1 : длительность 300.632405ms
2 : длительность 300.673701ms
3 : длительность 300.907795ms

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go run forgo2.go
2 : длительность 300.505724ms
0 : длительность 300.588106ms
1 : длительность 300.670501ms
3 : длительность 300.682411ms
И хорошо видно как горутины запускаются (точнее завершаются) в случайном порядке.
P.S. Хотите, присваивайте переменной то же имя i := i - в коде Go довольно часто можно увидеть - это такого рода своего пижонство... Не нравится - присваивайте другое имя j := i
Вложения
forgo2.go
(481 байт) 9 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Go: инструментарий (продолжение)

Непрочитанное сообщение Olej » 10 фев 2024, 03:26

Olej писал(а):
10 фев 2024, 03:05
Вот теперь всё играет в старой версии 1.18
Теперь нужно, обратным порядком, вернуться в свеже установденную версию 1.22:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ sudo update-alternatives --config go
[sudo] пароль для olej:
Есть 3 варианта для альтернативы go (предоставляет /usr/bin/go).

  Выбор   Путь              Приор Состояние
------------------------------------------------------------
  0            /usr/local/go/bin/go   85        автоматический режим
  1            /lib/go-1.13/bin/go    60        ручной режим
* 2            /lib/go-1.18/bin/go    75        ручной режим
  3            /usr/local/go/bin/go   85        ручной режим

Нажмите «enter», чтобы не менять текущий выбор[*], или введите нужное число: 0
update-alternatives: используется /usr/local/go/bin/go для предоставления /usr/bin/go (go) в автоматическом режиме

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go version
go version go1.22.0 linux/amd64
И заново переформировать mod.go:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ mv go.mod go.mod.18

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go mod init new.vers
go: creating new go.mod: module new.vers
go: to add module requirements and sums:
    go mod tidy

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go mod tidy
go: finding module for package golang.org/x/sync/errgroup
go: finding module for package github.com/go-board/std/slices
go: found github.com/go-board/std/slices in github.com/go-board/std v0.6.0
go: found golang.org/x/sync/errgroup in golang.org/x/sync v0.6.0

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ cat go.mod
module new.vers

go 1.22.0

require (
	github.com/go-board/std v0.6.0
	golang.org/x/sync v0.6.0
)

require github.com/tidwall/btree v1.7.0 // indirect

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Go: инструментарий (продолжение)

Непрочитанное сообщение Olej » 10 фев 2024, 03:30

Olej писал(а):
10 фев 2024, 03:26
Теперь нужно, обратным порядком, вернуться в свеже установденную версию 1.22:
Проверяем:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go build forgo2.go

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ go build forgo1.go
Исходные файлы всё те же, неизменные :!:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ ls -o forgo{1,2}
-rwxrwxr-x 1 olej 2100914 фев 10 01:49 forgo1
-rwxrwxr-x 1 olej 2101034 фев 10 01:48 forgo2
Размеры чуть отличаются, т.е. код - разный.
И выполнение:

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ ./forgo1
2 : длительность 300.482074ms
0 : длительность 300.589388ms
1 : длительность 300.646723ms
3 : длительность 300.642338ms

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ ./forgo2
2 : длительность 300.421238ms
1 : длительность 300.541565ms
3 : длительность 300.55707ms
0 : длительность 300.490542ms

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ ./forgo1
1 : длительность 300.569909ms
0 : длительность 300.500891ms
2 : длительность 300.642735ms
3 : длительность 300.920749ms

Код: Выделить всё

olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/compare/new.vers$ ./forgo2
0 : длительность 300.485186ms
3 : длительность 300.614011ms
2 : длительность 300.523596ms
1 : длительность 300.755501ms
И что мы видим :?:
Что нем не нужно вводить дополнительную локальную переменную внутри цикла for(...) {...}

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 11 гостей