@gogolang

Страница 761 из 1630
Marlik
21.01.2018
03:40:16
Так-то уже есть чем распарсить. decoder := json.NewDecoder(file) cnf := Config{} err = decoder.Decode(&cnf) Не улавливаю момент как мне подставить аргумент в return cnf.s (s это аргумент) . Пойду доку почитаю.

Andrew
21.01.2018
03:43:29
Так-то уже есть чем распарсить. decoder := json.NewDecoder(file) cnf := Config{} err = decoder.Decode(&cnf) Не улавливаю момент как мне подставить аргумент в return cnf.s (s это аргумент) . Пойду доку почитаю.
Стандартная json-либа вроде умеет только гонять данные в структуры и обратно. Соответственно, "подставить аргумент" ты можешь либо только через reflect, либо через другую либу парсинга json'а.

Marlik
21.01.2018
03:43:50
Стандартная json-либа вроде умеет только гонять данные в структуры и обратно. Соответственно, "подставить аргумент" ты можешь либо только через reflect, либо через другую либу парсинга json'а.
Всё оказалось проще. Сделал метод который просто возвращает Config: type Config struct { Name string `json:"name"` } func (cnf Config) GetFromConfig() string { file, err := os.Open("./config.json") if err != nil { log.Fatal(err) } defer file.Close() decoder := json.NewDecoder(file) err = decoder.Decode(&cnf) if err != nil { log.Panic(err) } return cnf } А что-бы получить из структуры какой то параметр, нужно так: v := Config{} v.GetFromConfig().Name Теперь сижу думаю, насколько это правильно и не криво-ли?

Google
Slava
21.01.2018
05:09:48
а ещё лучше, читать конфиг один раз при инициализации где-нибудь в main и пробрасывать внутрь

Marlik
21.01.2018
05:10:13
Ну это связано с хотелкой, не зашивать в код некоторые вещи. Например пишу бота, в config.json положил токен бота. Так как, токен может иногда меняться, то вот через внешний конфиг менять.

Marlik
21.01.2018
05:11:15
Andrew
21.01.2018
05:11:31
Да.
Тогда > токен может иногда меняться неверно.

Marlik
21.01.2018
05:12:42
Тогда > токен может иногда меняться неверно.
Почему не верно, написал приложение, отдал разным людям, каждый из них создал бота, в конфиг сунул свой токен.

Andrew
21.01.2018
05:13:54
Почему не верно, написал приложение, отдал разным людям, каждый из них создал бота, в конфиг сунул свой токен.
Капитан Дуров гарантирует, что токен не меняется, соответственно достаточно сам токен считать при запуске приложения.

Marlik
21.01.2018
05:14:00
Также например для конфигурации, сейчас один IP, завтра другой, сейчас например через nginx ловит, завтра сам слушает порт.

Капитан Дуров гарантирует, что токен не меняется, соответственно достаточно сам токен считать при запуске приложения.
Вы читали, что я написал? Я написал один раз приложение, которое можно использовать с разными токенами.

Поэтому внешний конфиг важен.

Slava
21.01.2018
05:16:28
может проще перезапустить приложение?

Andrew
21.01.2018
05:16:54
может проще перезапустить приложение?
или вызвать из своего приложения config.Reload()?

Google
Slava
21.01.2018
05:17:12
ну или так, на SIGUSR

Andrew
21.01.2018
05:17:19
Потому, что считывать каждый раз переменные из конфига на диске - это бред.

Alexander
21.01.2018
05:17:23
Вот так просыпаешься в 8 утра в воскресенье, а в чатике такая оживлённая дискуссия. Спасибо, парни! :)) То что надо под утренний чаёк :)

Marlik
21.01.2018
05:18:29
Потому, что считывать каждый раз переменные из конфига на диске - это бред.
А не бывает каждого раза! Это случается только при старте бота, всё!

Andrew
21.01.2018
05:19:03
Marlik
21.01.2018
05:19:32
может проще перезапустить приложение?
Без внешнего конфига не перезапустишь, а придётся компилить под каждого клиента, и зашивать в код его токены, айпишнеги.

Кэп, ты сам сказал "а вдруг токен поменяется".
Не вдруг, я знаю что поменяется.))

Andrew
21.01.2018
05:20:16
Без внешнего конфига не перезапустишь, а придётся компилить под каждого клиента, и зашивать в код его токены, айпишнеги.
Давай с самого начала. Конфиг должен быть во внешнем файле и считываться один раз при запуске программы.

Andrew
21.01.2018
05:21:00
Да.
Если пользователь меняет конфиг, он либо перезапускает приложение, либо вызывает ReloadConfig()

Alexander
21.01.2018
05:21:10
Ещё бы GoFlood не был мёртв ))
Мне, как новичку в программировании, много очень полезно. Продолжайте! Спасибо)

Marlik
21.01.2018
05:21:52
Что-бы понятнее было, вот начало бота: func main() { conf := Config{} bot, err := tgbotapi.NewBotAPI(conf.Config().TelegramBotToken) if err != nil { log.Fatal(err) } _, err = bot.SetWebhook(tgbotapi.NewWebhookWithCert(conf.Config().WebhooksURL+bot.Token, "public.pem")) if err != nil { log.Fatal(err) } updates := bot.ListenForWebhook("/" + bot.Token) go http.ListenAndServe(conf.Config().ListenLocal, nil) ... Тут дальше ловим апдейты.

Если пользователь меняет конфиг, он либо перезапускает приложение, либо вызывает ReloadConfig()
Нет, он ставит бота на сервер, в конфиге указывает токен, ип и прочее. И запускает бота.

Andrew
21.01.2018
05:23:53
Я ожидал увидеть такое: func main() { conf := LoadConfig() // считываем конфиг из файла bot, err := tgbotapi.NewBotAPI(conf.TelegramBotToken) }

conf.Config().TelegramBotToken что за метод Config()?

Andrew
21.01.2018
05:24:47
Marlik
21.01.2018
05:25:31
conf.Config().TelegramBotToken что за метод Config()?
func (cnf Config) Config() string { file, err := os.Open("./config.json") if err != nil { log.Fatal(err) } defer file.Close() decoder := json.NewDecoder(file) err = decoder.Decode(&cnf) if err != nil { log.Panic(err) } return cnf }

Так сделай ))
Пока не соображу как))

Google
Andrew
21.01.2018
05:28:07
Пока не соображу как))
Функция загрузка должна выглядеть так: func LoadConfig() (c *Config, err error)

Andrew
21.01.2018
05:29:47
Как то так (писал с утюга, могут быть ошибки): func LoadConfig() (c *Config, err error) { b, err := ioutil.ReadFile("./config.json") if err != nil { return nil, err } err = json.Unmarshal(b, c) if err != nil { return nil, err } return c, nil }

Marlik
21.01.2018
05:31:12
А почему ioutil.ReadAll(file) ?

Andrew
21.01.2018
05:34:51
А почему ioutil.ReadAll(file) ?
Сори, ReadFile() должен быть. К сожалению, мой утюг не пишет мне подсказки к Go коду ))

Переписал код, вроде так должно быть.

Сначала считал файл в b, затем отконвертировал байты в структуру.

Marlik
21.01.2018
05:40:34
Ну это просто функция. Я через метод пробую.

Но выглядит хорошо.))

Andrew
21.01.2018
05:42:18
Обычно через функцию все делают. :)

Если хочешь через метод, то нужно указатель использовать (звёздочку поставить): func (cnf *Config) Load() error

Ilya
21.01.2018
05:44:43
Почему емакс, а не вим? Для вим, вроде, хороший плагин.
Действительно хороший или как обычный плагин на вим, который жрет кучу цпу?

Slava
21.01.2018
05:48:06
в виме крутой плагин

Marlik
21.01.2018
05:48:42
Переписал код, вроде так должно быть.
Спасибо, оставлю ваш вариант.

Andrew
21.01.2018
05:48:57
Коллеги, такой вопрос. Мне нужно в несколько потоков обработать массив. Что я не так делаю? https://play.golang.org/p/Ez1Or17IYzn

Slava
21.01.2018
05:49:30
переменная v создаётся только один раз

ты её используешь в каждом цикле

Andrew
21.01.2018
05:49:54
Slava
21.01.2018
05:50:17
читай это как

var v

Google
Slava
21.01.2018
05:50:23
for v = range

Andrew
21.01.2018
05:50:56
Не-не-не, если убрать go func(), то всё работает, проблема не в range

Slava
21.01.2018
05:51:24
ты замыкаешь v внутрь горутины

когда цикл прошёл

твоя замыкнутая переменная указывает на память с последним элементом

Andrew
21.01.2018
05:52:25
Тогда что мне сделать, чтобы передавалось в каждую горутину своё значение?

Slava
21.01.2018
05:52:41
передавай как аргумент в функцию

или копируй внутри цикла

Andrew
21.01.2018
05:53:23
Slava
21.01.2018
05:53:27
не за что

это не фишка го

то же самое и в js и вдругих языках

так работают замыкания =)

кажется js программистов любят на собеседованиях спрашивать подобные вещи

у нас тут как раз много nodejs набежало

Andrew
21.01.2018
05:54:51
Хех, я из Free Pascal'я, у нас вообще таких фишек нету ?

/dev/null
21.01.2018
07:51:54
Ребят подскажите как реализовать API чтобы отдавать mp3 То есть со стороны клиента есть нечто вот такое (player.add('http://path-to-mp3.com/example.mp3');)

Не совсем пойму как это реализовать на бэке, или просто отдавать ссылку на файл?

Google
Zloy Dobriy
21.01.2018
07:52:27
Просто ссылку

Как еще то

/dev/null
21.01.2018
07:52:35
ясно спс

Как еще то
Да хз, раньше не сталкивался с подобной задачей, думал есть еще какие решения

Alexey
21.01.2018
11:45:49
Привет

Подскажите плз

package main import ( "flag" "fmt" "log" "x/ssh" ) func main() { pool := flag.String("p", "", "IP format 192.168.1.0/24") flag.Parse() hosts, err := ssh.GenerateHosts(*pool) if err != nil { log.Fatalf("[ERROR] %v\n", err) } jobs := make(chan string, len(hosts)) results := make(chan string, 3) for w := 1; w <= 3; w++ { go ssh.Scan(w, jobs, results) } for _, host := range hosts { // fmt.Print(host + "\n") jobs <- host } close(jobs) for i := 0; i < len(hosts); i++ { fmt.Print(<-results) } }

Почему то прозодит всего три итерации и ждет А вот когда w < len(hosts)

проходит все итерации

Я так понимаю горутина живая и ждет сообщения в канале, но я вроде как сразу все jobs отдал

Там где ssh.Scan просто for j := range jobs {}

По идее же должны все jobs пройтись в тех же трех горутинах, но что-то не так

В общем я хочу вот так

https://play.golang.org/p/FDaZZ_b4Ocd

Может быть какая то особенность реализации?

А вот так все работает

package main import ( "flag" "fmt" "log" "x/ssh" ) func main() { pool := flag.String("p", "", "IP format 192.168.1.0/24") flag.Parse() // 64.254.32.0/24 hosts, err := ssh.GenerateHosts(*pool) if err != nil { log.Fatalf("[ERROR] %v\n", err) } jobs := make(chan string, len(hosts)) results := make(chan string, 3) for w := 0; w < len(hosts); w++ { go ssh.Scan(w, jobs, results) } for _, host := range hosts { // fmt.Print(host + "\n") jobs <- host } close(jobs) for i := 0; i < len(hosts); i++ { fmt.Print(<-results) } }

Но я хочу сделать не 254 воркера(w := 0; w < len(hosts); w++), а всего 10

Alexander
21.01.2018
11:55:40
Вместо подсчета количества результатов в канале лучше использовать WaitGroup

Страница 761 из 1630