.
?
🏁Александр
однажды ты проснешься что тебе понадобились models в main и получишь циклическую зависимость
🏁Александр
ну пример утрированный конечно
.
А с чего бы она там должна появиться?
.
Если у вас структура продумана, таких ситуаций быть не должно
Kirill
если появилась такая необходимость, то ты уже где то ошибся, имхо
Aleksandr
ошибся
Slava
https://blog.golang.org/go-cloud
🏁Александр
а как же надо? :)
Vladislav
Ещё был доклад на гоферконе российском.
Anonymous
всем привет
вопрос по телеграм боту
почему он падает/ точнее дебаг завершается после первой отправки сообщения юзеру хотя я хочу несколько сообщений отправить?
for update := range updates {
//some actions
createSlice := funcCreate()
if update.Message != nil {
if len(createSlice) == 1 {
msg, description := doSomeWork(createSlice[0], update.Message.Chat.ID)
bot.Send(msg)
//заполняю некоторыми данными msg и отдельно беру description чтобы отослать в отдельном сообщении
//но дебаг бота завершается после первой отправки
//почему?
msgDescription := tgbotapi.NewMessage(update.Message.Chat.ID, description) // это уже не ловится дебагом
bot.Send(msgDescription)
} else if len(createSlice) > 1 {
msg, description := doSomeWork(createSlice[i], update.Message.Chat.ID)
bot.Send(msg)
msgDescription := tgbotapi.NewMessage(update.Message.Chat.ID, description)
bot.Send(msgDescription)
}
}
}
Aleksandr
текст ошибки приведи
Anonymous
в goland нет ошибок просто выходит как то из дебага в vs code
Failed to continue.
Anonymous
в функции doSomeWork
msg, description := doSomeWork(createSlice[i], update.Message.Chat.ID)
bot.Send(msg)
выполняется такой код
msg := tgbotapi.NewPhotoUpload(chatID, fileName)
msg.Caption = data.Name
description = data.Description
return msg, description
Aleksandr
маловато данных
Anonymous
по сути логика следующая
//возвращает файл/картинку название и описание
file, caption, description := doSomething(slice[0], chatID)
//отдаем все юзеру
msg := tgbotapi.NewPhotoUpload(chatID, file)
msg.Caption = caption
bot.Send(msg)
//сюда уже не проходит
// те после картинки и названия идет подробное описание
msgDescription := tgbotapi.NewMessage(chatID, description)
bot.Send(msgDescription)
Anonymous
это не работает только в дебаге
Anonymous
без дебага вся последовательность отрабатывает
Anonymous
но так я не могу проследить то что мне нужно(
Aleksandr
мало данных
Slava
https://twitter.com/sethvargo/status/1021887669368811520
heavycharged
ребятки, если в QueryContext() передавать контекст, и во время одного из вызовов rows.Next() он будет закрыт, то rows.Next() вернет false и цикл прервется?
heavycharged
судя по всему, сам запрос - отдельно, а роусы к нему отдельно, и их сканнинг от контекста не зависит.
Pawel
heavycharged
я гляну чуть позже на него, а кто-то возвращает коллекцию из базы через канал?
т.е., делает запрос, получает ответ, создает канал, запускает горутину сканирующую значения, и сразу же возвращает канал, а горутина сканирует и пишет в канал отсканненые модели.
heavycharged
вроде отправка в канал не очень быстрая
heavycharged
ну т.е. может лучше аппендить в слайс и его возвращать.
heavycharged
кто-то может заморачивался по этому поводу или имеет какие-то мысли?
heavycharged
аппенд в слайс ок, но когда у нас выборка например товаров штук 100000, нужно курсором как-то читать, чтобы все в память не писать.
heavycharged
думаю может сделать два метода, для маленьких выборок - слайсом возвращать, а для больших, что-то вроде курсора придумать.
Daniel
вроде отправка в канал не очень быстрая
опять...
где вы этого нахватались?
вы только что по сети сходили, подождали выборку, распарсили ответ. канал на этом фоне вы даже померять не сможете.
но "вроде не очень быстрая"
heavycharged
ну если сравнить отправку в канал, и аппенд в слайс
Daniel
зачем их сравнивать?
Daniel
что вы от результата ждете?
heavycharged
затем, что это два альтернативных варианта как получать данные из базы, через канал, или уже готовый слайс.
Daniel
так вот, при прочих расходах эти два метода одинаковые, занимают 0. но канал при этом уже способен работать с горутинами
heavycharged
ну т.е. вы говорите, что канал "чуть лучше" в этом плане?
Daniel
канал существенно лучше для передачи чего бы то ни было между горутинами
heavycharged
окей, наверное тогда попробую пойти по пути каналов.
Anton
всем 👋 правильно ли я делаю: допустим, мне нужен некий тип ShortTime, который как бы "наследуется" от time.Time, и у него я просто хочу переопределить методы MarshalJSON и UnmarshalJSON, чтобы при работе с json он понимал строки типа "15:00", "12:20" и т.д.
пробовал делать так:
type ShortTime time.Time
но тогда при работе с ним его нужно постоянно "конвертировать" в/из time.Time, например,
func (st *ShortTime) DoSomething() {
t := time.Time(*st)
// сделать что-то с t
*st = &ShortTime{t}
}
остановился на варианте "embedding":
type ShortTime struct {
time.Time
}
таким образом все методы time.Time доступны сразу на переменной типа ShortTime, но тут тоже возникает вопрос, использовать embedding time.Time или через поинтер *time.Time.
Daniel
а зачем через поинтер?
Anonymous
всем 👋 правильно ли я делаю: допустим, мне нужен некий тип ShortTime, который как бы "наследуется" от time.Time, и у него я просто хочу переопределить методы MarshalJSON и UnmarshalJSON, чтобы при работе с json он понимал строки типа "15:00", "12:20" и т.д.
пробовал делать так:
type ShortTime time.Time
но тогда при работе с ним его нужно постоянно "конвертировать" в/из time.Time, например,
func (st *ShortTime) DoSomething() {
t := time.Time(*st)
// сделать что-то с t
*st = &ShortTime{t}
}
остановился на варианте "embedding":
type ShortTime struct {
time.Time
}
таким образом все методы time.Time доступны сразу на переменной типа ShortTime, но тут тоже возникает вопрос, использовать embedding time.Time или через поинтер *time.Time.
ИМХО, тут поинтер не нужен
Anton
да чёрт его знает, в этом в принципе тоже вопрос, нужен ли поинтер. у меня с ними пока не очень простые отношения, т.к. нет бэкграунда нормальных языков, только js 🤷♀️
Daniel
ага
Daniel
тогда не пользуйте пока :)
Daniel
как вылезет "я меняю значение, а оно не меняется" - так и поймете, где использовать поинтер
Anton
с поинтерами пока не могу сказать, что мне всё понятно, потому что тут ещё есть особенности реализации библиотек. например, если я использую github.com/satori/go.uuid и определяю модели типа
type Model struct {
ID *uuid.UUID `json:"id,omitempty"`
Name string `json:"name,omitempty"`
}
то для ID мне нужен поинтер с точки зрения реализации библиотеки satori/go.uuid, потому что иногда я хочу его скрыть из ответа, и если там был бы не поинтер, а просто uuid.UUID, а значения не было бы, то оно отдавало бы "нулевой" uuid, "00000000-0000-0000-0000-000000000000", а так я могу ему сделать m.ID = nil, и его не будет.
хотя я бы с радостью и тут не использовал поинтеры.
V
но ведь это фича джейсон маршаллинга
Anton
вот кстати про этот вопрос, правильно ли я понимаю, что omitempty игнорирует нулевые значения в кастомных MarshalJSON методах? например,
type MyUUID struct {
uuid.NullUUID
}
type Model struct {
ID MyUUID `json:"id,omitempty"`
}
func (u MyUUID) MarshalJSON() ([]byte, error) {
fmt.Println("valid", u.Valid)
if !u.Valid {
return json.Marshal(nil)
}
return json.Marshal(u.NullUUID)
}
m := Model{}
json.NewEncoder(os.Stdout).Encode(m)
valid false
{
"id": null
}
Anton
т.е. то, что там omitempty, а маршалится nil, ему как бы всё равно
Anton
и единственный способ — использовать поинтер
V
omitempty в этой либе игнорируется, т.к. там свой кодек, который переопределяет UnmarshalText
Anonymous
всем привет
снова вопрос по hugo
не могу понять почему он не тянет css
в themes/theme-name/layouts
определены laytouts для страниц
в partials определены header & footer в которых берутся css из каталога project/static/css
на основе project/archtypes/default.md создается файл по шаблону project/themes/theme-name/layouts/items/single.html
в котором также прописаны {{partial "header.html" . }} и {{partial "footer.html" . }}
= project/content/item.md
но вот стили css к нему уже не тянутся
не понимаю (((
Anonymous
Pawel
Anton
это наркомания :(
Anton
а это вот *st = &ShortTime{t} ?
логика такая была, например, нужен метод, который добавляет 1 час:
type ShortTime time.Time
func (st *ShortTime) AddOneHour() {
t := time.Time(*st)
// тут добавляем час
// и через поинтер присваиваем в st новое значение
*st = &ShortTime(t)
}
то, что там фигурные скобки — очепятка, имел в виду круглые
Daniel
нет, с круглыми ничего не выйдет
Anton
если ShortTime struct, то да
Anton
а это пример был когда type ShortTime time.Time
Daniel
а если нет, то & перед ней будет ошибкой
Daniel
а, ок
Anton
да, & лишний
Pawel
да я к тому что там как раз таки через пойнтер надо метод делать
Anonymous
тут вопрос назрел. go vs c# ?
E
🤦♂️
Aleksey
Если холивара, то победит гладиолус.
Anonymous
язык хочу быстрый серверный
Olzhas
Sebor▂▅▇█▓▒░
Anonymous
я не хочу холивара я хочу какой то обьективной оценки чтобы понимать что у го есть какой то смысл вообще