Ответы пользователя по тегу Go
  • Как bytes.Buffer создает новый срез байтов через new?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    new возвращает всегда ненулевой указатель на аллоцированную память типа, который вы укажете в аргументе.

    В Го перегрузки методов нет, тем более встроенных функций.

    type Buffer struct {
    	buf      []byte // contents are the bytes buf[off : len(buf)]
    	off      int    // read at &buf[off], write at &buf[len(buf)]
    	lastRead readOp // last read operation, so that Unread* can work correctly.
    }


    new(bytes.Buffer) не аллоцирует память под buf. Он будет nil. Только под саму структуру Buffer.
    Ответ написан
    Комментировать
  • Как сделать поиск по $in и $nin для одного поля в aggregate mongodb?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    duplicate field name Key in struct literal

    Так в ошибке все написано. Вы неправильно создали структуру.

    bson.D это массив из bson.E, где у bson.E есть поля Key и Value, соответственно в Го такой код должен быть:
    matchFilter := bson.D{
    		bson.E{
    			Key: "$match",
    			Value: bson.D{
    				bson.E{
    					Key: "roommates",
    					Value: bson.D{
    						bson.E{Key: "$in", Value: []int{123}},
    						bson.E{Key: "$nin", Value: []int{3123}},
    					},
    				},
    			},
    		},
    	}


    bson.E можно опустить, поэтому в примерах непонятные {{ появляются.
    Ответ написан
    1 комментарий
  • Как в GO pool worker остановить горутины?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Горутины нельзя останавливать извне. Так гласит документация по языку.

    В вашем примере остановить выполнение горутин можно только если закрыть канал jobs.
    Ответ написан
    Комментировать
  • Почему локальные пакеты не видит VS Code?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Используйте модули.
    GOPATH подход устарел и существует только для обратной совместимости.
    https://go.dev/blog/using-go-modules
    https://go.dev/ref/mod

    Чтобы в модулях использовать локальные пакеты, через replace укажите к ним путь.
    Ответ написан
    Комментировать
  • Как запустить python-скрипт с таймаутом из Go?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    В документации os/exec даже есть пример под ваш случай: https://pkg.go.dev/os/exec#example-CommandContext
    Ответ написан
    Комментировать
  • Почему не устанавливается пакет chi с помощью go get?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Вики по GOPATH.
    GOPATH подход устарел и с 1.16 версии по умолчанию используются модули.

    Если вам так нужен проект в GOPATH, то можно отключить модули:
    GO111MODULE=off go get github.com/go-chi/chi/v2

    В режиме модулей зависимости сохраняются в кэше.
    Их можно перенести в проект командой go mod vendor, и зависимости перенесутся в папку vendor рядом с файлом go.mod.

    При сборке проекта зависимости автоматически скачиваются в кэш.
    Ответ написан
    1 комментарий
  • Когда использовать RWMutex вместо Mutex?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    В случае с обычным мьютексом возможен только эксклюзивный доступ к ресурсу, т.е. только один поток имеет доступ для чтения или записи.
    А когда у нас RWMutex, то количество потоков при чтении неограниченно, но при обращении на запись доступ становится опять эксклюзивным только для одного потока.

    RWMutex используется для увеличения пропускной способности, когда к ресурсу чаще обращаются на чтение, чем на запись.
    Ответ написан
    Комментировать
  • Зачем нужны "ссылочные" методы и почему они не удовлетворяют интерфейсам?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    *Human и Human это два абсолютно разных типа данных.
    Значит и реализацию для интерфейсов для каждого типа надо делать отдельно.

    *Human - указатель на значение типа Human.
    Ответ написан
    Комментировать
  • Как корректно занести объект с полем ObjectID в MongoDB (Golang mongo-driver)?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Все правильно, вы при отправке посылаете такой _id, потому что у вас в структуре это значение идет по умолчанию.

    Есть несколько вариантов решения вопроса:
    1) Использовать разные структуры для получения и отправки, где в структуре для вставки не будет поля _id, тогда монга сама задаст значение для id.
    2) Либо генерировать id на клиенте через primitive.NewObjectID()
    в вашем случае:
    testIndicator := db.Indicator{
        ID: primitive.NewObjectID(),
        ...
      }

    3) Использовать *primitive.ObjectID в качестве типа для ID, nil будет значением по умолчанию, тогда монга создаст объект сама.
    Ответ написан
    Комментировать
  • Как нарисовать точку на канве fyne (go)?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Смотрите часть с canvas.Raster:
    raster := canvas.NewRasterWithPixels(
    		func(_, _, w, h int) color.Color {
    			return color.RGBA{uint8(rand.Intn(255)),
    				uint8(rand.Intn(255)),
    				uint8(rand.Intn(255)), 0xff}
    		})
    Ответ написан
  • Какие есть подходы для стабилизации потребляемой памяти в го-приложении?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Если нужно мутировать много строк, то не используйте строки, а работайте с байтами. Пакет bytes в помощь.

    Используйте sync.Pool для уменьшения количества аллокаций.

    Ограничивайте количество одновременных запросов. Тут могу посоветовать использовать семафор с весами. Идея в том, чтобы задать каждому запросу свой вес и при переполнении семафора остановить обработку новых запросов до тех пор, пока ресурс не освободится. Здесь главное ввести лимит на максимальное количество соединений, после которого можно и дропать запросы (сейчас у вас по сути то же самое происходит, но из-за падения сервиса, что намного хуже).

    В самом крайнем случае можно попросить рантайм освободить занятую память:
    runtime.GC()
    debug.FreeOSMemory()
    Ответ написан
    Комментировать
  • Многократное использование len() или кеширование в переменную?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Дескриптор у слайса имеет такую структуру:
    type SliceHeader struct {
            Pointer uintptr
            Len  int
            Cap  int
    }


    len(...) - это ключевое слово языка и в контексте компилятора не является функцией, вместо которой он может подставить что угодно.

    Выше мы выяснили, что у слайса есть поле с длиной, соответственно нет смысла кешировать длину в отдельной переменной. Т.к. компилятор просто заменит вызов len на обращение к полю в дескрипторе слайса. Он вообще может переместить длину в регистр процессора и не обращаться к ram при итерации.

    Если нужно экономить ресурсы, то лучше подумайте о неявной проверке на выход за границы массива, которая в некоторых случая может сожрать нехилую часть процессорного времени. Подробнее прочитать можно в этой статье.
    Ответ написан
    1 комментарий
  • Как узнать когда горутины закончили запись, чтобы закрыть канал?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Предлагаю не злоупотреблять каналами:
    https://goplay.tools/snippet/a91nAx2wevG

    Ваш тест из вопроса проходит. Корректность теста не смотрел :)
    Ответ написан
    Комментировать
  • Почему не видит пакет race?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Если устанавливали по инструкции с сайта, то удаляйте все что напихали в систему. Потом нужно установить компилятор через менеджер пакетов.
    Например, для debian/ubuntu через apt:
    sudo apt install golang
    Либо через snap:
    sudo snap install go --channel=1.16/stable --classic
    Ответ написан
    Комментировать
  • Как организовать тесты в пакетах вида адаптер?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Проблема в том что эти адаптеры имеют одни и те же методы, делают одно и тоже (но по своему),

    Это заворачивается в интерфейс и тестируете по этому интерфейсу ваши конкретные реализации.
    https://gobyexample.com/interfaces

    пример repo_test.go:
    type Repository interface{
        MethodA() error
        MethodB() error
    }
    
    func TestRedis(t *testing.T) {
         testRepo(t, NewRedis(...))
    }
    
    func TestMongo(t *testing.T) {
         testRepo(t, NewMongo(...))
    }
    
    func testRepo(t *testing.T, repo Repository){
        err := repo.MethodA()
        if err != nil {
            t.Errorf("methodA: %s", err)
        }
    
        err = repo.MethodB()
        if err != nil {
            t.Errorf("methodB: %s", err)
        }
    }


    ... но тут проблема с цикличным импортом (все адаптеры импортируют компоненты из repo).

    Но тут можно только посочувствовать.
    Самое простой выход из ситуации - это отдельный пакет, в котором будут тестироваться интерфейсы по схеме, которую я выше описал.
    Ответ написан
    Комментировать
  • Не определены стандартные пакеты Golang?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Никогда не устанавливайте программы вручную в корень системы, как в вашей инструкции. Почти всегда есть готовые пакеты. Лучше уже через докер ставить, лезть в систему - крайний случай.
    (и советую все вернуть как было до ручной установки)

    Го лучше поставить через snap (а вот vscode лучше через deb с сайта):
    sudo snap install go --channel=1.16/stable --classic


    Когда понадобятся другие версии, VScode может сам установить в папку желаемую версию и будет использовать её:
    ctrl+shift+p, вводите Go: Locate Configured Go Tools (или на панели снизу можно найти кнопку).

    Бывает что анализатор может заглючить и перезапуск gopls помогает: ctrl+shift+p, Go: Restart language Server

    И убедитесь, что го расширение установлено в редактор.
    Ответ написан
    Комментировать
  • Есть ли простой способ передать задачу в Go?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Пример замыканий:
    package main
     
    import (
        "fmt"
        "math/rand"
        "time"
    )
     
    type kelvin float64
     
    func measureTemperature(samples int, sensor func() kelvin) { // measureTemperature принимает функцию в качестве второго параметра
        for i := 0; i < samples; i++ {
            k := sensor()
            fmt.Printf("%v° K\n", k)
            time.Sleep(time.Second)
        }
    }
     
    func fakeSensor() kelvin {
        return kelvin(rand.Intn(151) + 150)
    }
     
    func main() {
        measureTemperature(3, fakeSensor) // Передает название функции другой функции
    }

    Источник
    Ответ написан
    2 комментария
  • Как огрганизовать хранение нескольких value в boltdb и поиск по ним?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    И при каждом запросе перебирать каждый элемент, сравнивать по полям структуры с нужными данными?

    bolthold

    Будет ли это быстро когда база вырастит до 10 000 полей.

    Нужно смотреть конкретно в ваших задачах.

    В пользу SQLite можно отнести поддержку sql запросов, что позволяет использовать стандартные подходы к построению базы данных. Например, можно воспользоваться маппером sqlx или gorm.
    Ответ написан
    Комментировать
  • Go под Android?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    Из коробки все компилируется:
    GOOS=android GOARCH=arm GOARM=7 go build

    И джавы вообще никакой не надо, как и графической оболочки :)
    Лучше вообще на Го забыть про всякие там новомодные gui - только консоль, только хардкор.

    Если так хочется как можно больше на Го сделать, то решением может быть библитека на нем, а фронт на нативных технологиях: Java/Kotlin или Dart.

    Еще есть вариант в виде привязки к Qt, логику можно писать на Го, графику на QML. Только вот придется весь набор Qt либ тянуть с собой, да и ограничения в лицензировании продукта есть.
    Ответ написан
    7 комментариев
  • Как изменить двумерный массив в for?

    WinPooh32
    @WinPooh32
    Stack Overflow answer searching expert
    ....  
     for i, _ := range arr {
        arr[i] = append(arr[i], "ddddd")
      }
    ....

    В вашем случае innerArray это срез, который внутри содержит указатель на массив, но когда вы делаете append и при этом size выходит за пределы capacity, то выделяется новый массив и в него добавляется новое значение.

    К тому же innerArray это локальная переменная в виде среза, которая доступна лишь в пределах цикла.
    Присваивая новое значение в нее из append() вы не меняете значение переменной среза в массиве, а новый срез из аппенда уже указывает на другой массив с добавленным элементом.
    Ответ написан
    Комментировать