Ответы пользователя по тегу Go
  • Как правильно перобразовать типы в int полученные из JSON?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    var s struct {
    	I int
    }
    json.Unmarshal([]byte(`{"I": 5}`), &s)
    fmt.Println(s.I) // 5

    работает прекрасно.

    Ещё вы можете int64 привести к int с помощью int()
    var i64 int64 = 5
    var i int = int(i64)
    fmt.Println(i)	// 5
    Ответ написан
    Комментировать
  • Как лучше собирать данные из нескольких потоков, для последующей отправки клиенту?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Зачем ва Go, если вы не поняли его основную парадигму "share by communication"?
    Вам тут, из того, что я понял, определённо нужны каналы. Потому что много потоков + одна структура + заполнение по таймеру навевает мысли что творится полный пихжну.
    Опишите задачу получше.
    Ответ написан
    Комментировать
  • Как сделать удобную разработку?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Собственно, автоматизировать все процессы. Сделать это с помощью систем сборки (cmake, make, etc.) или с помощью shell скрипта, а может ваша IDE сразу поддерживает кастомные билд инструкции, тогда через них можно.

    например, кусок из моего скрипта:
    rsync -vazR project_folder username@${HOST}:/opt/go/src # заливаем файлы на сервер
    ssh username@${HOST} 'go build -v project_folder' # билдим
    ssh root@${HOST} 'systemctl restart project;' # перезапускаем юнит
    Ответ написан
    4 комментария
  • Как в ubuntu через systemd писать логи паники в Go?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Если сервер запускали через юнит systemd, то логи из него в journalctl -u unit_name. Весь оутпут пишется в stdout (консоль), которая перехватывается systemd и обрабатывается. Зачем вам файлы?
    Ответ написан
    6 комментариев
  • Как реализовать интерфейс в Go?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Вы реализовали интерфейс для типа "указатель на IPAddr", а распечатываете тип "IPAddr".

    С этим возникает сложность из-за двойных стандартнов, принятых в Go, хотя и логичных. Запомните навсегда:

    Pointer type can access the methods of its associated value type, but not vice versa. That is, a *Dog value can utilize the Speak method defined on Dog, but as we saw earlier, a Cat value cannot access the Speak method defined on *Cat.


    То есть в вашем случае всё бы работало и при правильном совпадении типов И при неправильной, противоположной вашему коду ситуации - если бы вы реализовали интерфейс для самого типа, а пытались распечатать указатель на него.

    Объясняется это просто - если метод реализован для указателя, он, скорее всего, может что-то менять в объекте по этому указателю, поэтому передавая объект по значению, а не по указателю - он бы менял не в самом объекте, а в его копии, которая бы делалась при передачи по значению. Это явно не то, чего ожидал писатель метода.
    В обратном же случае, если метод определён для типа по значению, а не по указателю, очевидно что метод ничего в самом значении не меняет (если бы попытался, то менял бы опять же в копии значения). А раз он там ничего не меняет, можно смело передать наш объект под ссылкой.

    Тут объясняется всё подробно: https://github.com/golang/go/wiki/MethodSets
    Ответ написан
    8 комментариев
  • Область использования языка GO?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Рассматривайте Go как что-т осрденее между явой и плюсами. Соответственно, всё сделать можно, особенно учитывая, что Go может работать с С кодом. А писать GUI на нём так же, как на C++, только либ ещё меньше. Есть биндинги Qt.
    Ответ написан
    1 комментарий
  • Что такое емкость среза?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    https://blog.golang.org/slices прочитайте и всё станет понятно.

    Если кратко, то ёмкость слайса - длина массива, который хранит элементы слайса. Попросту говоря это Байты оперативки, выделенные под хранение ваших данных. Оно всегда больше или равно длины слайса.
    Сам слайс это указатель на какой-либо из элементов в этом масиве (не оьязательно первый) + длина. Это искуственное ограничение, фактически это отрезок массива, в котором что-то записано. При добавлении в слайс нового элемента слайс увеличит свою длину на 1, пооказывая что кол-во данных в массиве увеличилось на 1, а емкость самого массива не изменится, если её хватало для хранения нового элемента. Если же весь массив был заолнен, то слайс просто выделит новый массив в памяти большей ёмкости (обычно в два раза большей предыдущей ёмкости) и перенесёт все данные туда вместе с новым добавленным элементом. При этом, очевидно, сам слайс не изменит своей длины, т.к. Кол-во данных не изменилось, а только поменяет указатель на начальный элемент, т.к. Массив с данными выделен новый по новому адресу в памяти.
    Ответ написан
    Комментировать
  • Как узнать количество прикреплённых файлов на go?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Не нужно так, нужно делать multipart и выставить инпуту с файлами аттрибут multiple
    sanatgersappa.blogspot.ru/2013/03/handling-multipl...
    Ответ написан
    Комментировать
  • Можно ли блокировать 1 ключ вместо всей карты?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    У меня чувство дежавю на этот вопрос. и не зря, я тебе уже отвечал на него:
    Потокобезопасность и указатели. Нужны блокировки?

    И ещё, на русском не говорят "карта" применительно к структуре данных map.

    Ты задал уже больше 100 вопросов, ответ на 95% из них гуглится не дольше пяти секунд. Может быть ты гуглишь на русском, а не на английском, раз у тебя всё время "Только вот как это уже не гуглится чёт."
    Ответ написан
    1 комментарий
  • Смаршалить в JSON поля внешней структуры через метод внутренней, или один метод для всех типов?

    evnuh
    @evnuh Автор вопроса
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Решение дали на stackoverflow и как подсказал Никита

    Решение простое -
    func Save(i interface{}, id int) {
        data, err := json.Marshal(i)
        check(err)
        if id == 0 {
            _, err = app.DB.Exec(`INSERT INTO users(data) VALUES ($1) `, string(data))
        } else {
            _, err = app.DB.Exec(`UPDATE users SET data = $1 WHERE id=$2`, string(data), id)
        }
        check(err)
    }

    и вызывать
    u := User{}
    a := Admin{}
    
    Save(u, u.ID)
    Save(a, a.ID)


    Мне потом ещё потребовалось присваивать ID, вернувшееся из базы обратно в структуру, поэтому я сделал
    interface Model {
        getID()
        setID()
    }

    Сделал реализацию этого интерфейса для User и использовал его вместо interface{}
    func Save(i model) {
    	data, err := json.Marshal(i)
    	var id int
    	check(err)
    	if i.getID() == 0 {
    		err = app.DB.QueryRow(`INSERT INTO users(data) VALUES ($1) RETURNING id`, string(data)).Scan(&id)
    		i.setID(id)
    	} else {
    		_, err = app.DB.Exec(`UPDATE users SET data = $1 WHERE id=$2`, string(data), i.getID())
    	}
    	check(err)
    }
    Ответ написан
    Комментировать
  • Как найти узкие места?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    гугл гугл гугл гугл гугл гугл гугл гугл гугл гугл
    https://habrahabr.ru/company/badoo/blog/301990/
    Ответ написан
    3 комментария
  • Потокобезопасность и указатели. Нужны блокировки?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Maps в Go не потокобезопасны, поэтому да, нужны локи.
    Ответ написан
  • Какой путь у новичка в Go?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Go идеален для новичков, потому что он сделал процесс входа в язык максимально простым. И так, схема действий:
    1) https://tour.golang.org/ - проходим весь курс. Самое важное в этом туре - это задачи. Они занимают 80% времени, но дадут 95% понимания и главное что вы лучше всё запомните
    2) Effective Go читаем полностью.

    Всё, вы уже можете считать себя программистом на Go и будете понимать почти всё о чём говорят другие программисты.

    На оба этих шага вы потратитен пару дней. Я уверен, что любые книги про Go вам в итоге не дадут больше информации, чем эти два шага, зато сожрут кучу времени.
    Ответ написан
    Комментировать
  • Как исправить ошибку main.go:1:16: expected ';', found 'import'?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    main.go:1:16: expected ';', found 'import'

    Вы нас обманываете приведённым листингом кода, т.к. компилятор видит `import` на первой строчке на 16 позиции файла `main.go`
    Ответ написан
    9 комментариев
  • Какой язык выбрать под Backend высоконагруженного rest-сервиса?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Ну выбора у вас не много.
    Го - на порядки проще, особенно при работе с вашими задачами (http/json/db)
    C++ - в разы быстре Го, но и в разы тяжелее вам будет работать с ним
    Пока у вас не миллионы онлайна и живёте вы на PHP, спокойно переходите на Go, его хватит надолго.
    Ответ написан
    2 комментария
  • Что выбрать для парсинга больших xml?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    golang + tarantool. Вот бенчмарк тарантула tarantool.org/benchmark.html, гле workload F - ваш случай.

    В golang прекрасный потоковый парсер xml по токенам. Сам писал парсер на нём для YML файлов, работает молниеносно.
    Ответ написан
  • Как распарсить xml с кодировкой windows-1251?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    import (
        "encoding/xml"
        "golang.org/x/net/html/charset"
    )
    
    decoder := xml.NewDecoder(reader)
    decoder.CharsetReader = charset.NewReaderLabel
    err = decoder.Decode(&parsed)


    Гугл мне помог найти ссылку stackoverflow.com/questions/6002619/unmarshal-an-i...
    Ответ написан
    Комментировать
  • Где набраться опыта GO программисту?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Ваш вопрос звучит так: "Я купил снегоход, что с ним делать?"
    Ответ написан
    Комментировать
  • Развертывание web приложения на Go?

    evnuh
    @evnuh
    Поиск Гугл помог мне, впусти и ты его в свой дом
    Как это работает, чтобы понимали. Я опишу истинно правильный путь, но долгий: (как подсказал pygame , по бенчмаркам https://gist.github.com/hgfischer/7965620 всё же нативный хттп сервер в Go быстрее, чем nginx с fcgi, т.к. у Go гавняная реализация fcgi, поэтому вместо fcgi быстрее будет обычный http proxy_pass).

    1) Ставится веб-сервер нормальный, а не тот, который есть в самом Go. То есть, ставим nginx. Настраиваем ему все url маршруты, настраиваем отдачу статики.

    2) За динамикой nginx будет обращаться к нашему Go демону. По протоколу fast-cgi. Именно по нему, потому что nginx его умеет и вообще он хорош (upd: но не в Go). Это короч бинарный протокол по которому nginx передаёт в нашу Go программу HTTP заголовки запроса от браузера и получает обратно HTTP ответ. Для этого ставим простейшую обёртку для fast-cgi под названием spawn-fcgi, она будет преднастраивать и запускать нашу Go программу, готовую для общения по протоколу fast-cgi.

    3) На случай, если наша Go программа падает. Либо уже у нас есть система, которая следит за демонами и поднимает их в случае падения (systemd, upstart), тогда конфигурируем её, либо ставим таковую и тоже конфигурируем.

    Привожу пример как это всё сделано у меня (самый популярный стек технологий) на Debian:

    1) nginx
    server {
    	server_name otboi.****;
    	listen 80;
    	include fastcgi_params;
    ...
    	
    	location / {
    		fastcgi_pass unix:/var/run/otboinik.sock;
    	}


    2) systemd конфиг, который стартует нашу Go программу, завёрнутую в spawn-fcgi
    [Unit]
    Description=Otboinik
    
    [Service]
    Restart=always
    Environment=OTBOINIK_BIN=/opt/гыы/otboinik/bin/otboinik
    Environment=OTBOINIK_PID=/var/run/otboinik.pid
    Environment=OTBOINIK_USER=гыыыы
    Environment=OTBOINIK_SOCKET=/var/run/otboinik.sock
    Environment=OTBOINIK_SOCKET_USER=гыыыыы
    Environment=OTBOINIK_SOCKET_MODE=0666
    ExecStart=/usr/bin/spawn-fcgi -s $OTBOINIK_SOCKET -M $OTBOINIK_SOCKET_MODE -n -P $OTBOINIK_PID -u $OTBOINIK_USER -U $OTBOINIK_SOCKET_USER -G $OTBOINIK_SOCKET_USER $OTBOINIK_BIN
    
    [Install]
    WantedBy=multi-user.target


    3) Сам Go код
    import (
    	"net/http"
    	"net/http/fcgi"
    )
    
    type Server struct {
    }
    
    func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
           // чиста пример
            jsonblob := r.FormValue("events")
    	if jsonblob == "" {
    		w.WriteHeader(http.StatusNotAcceptable)
    		return
    	}
    }
    
    func main() {
    	server := Server{}
    
    	func() {
    		fcgi.Serve(nil, server)
    	}()
    
    	waitchan := make(chan int, 1)
    	<-waitchan
    }
    Ответ написан
    4 комментария