Это вы утверждаете, что человек должен отказаться от своих привычек и посвятить свое время поискам альтернативы инструменту, который его устраивает. При этом в качестве мотивации вы продвигаете "он почти не хуже" и "мир во всем мире".
Для того, чтобы кто-то стал анализировать наличествующие альтернативы - покажите преимущества.
Человек абсолютно адекватно написал: "профитов от линя для него нет". И это ваша задача - обозначить профиты, а не его - засирать линь по надуманным поводам.
потому что вопрос состоял изначально в том, чем именно не угодил тот или иной продукт/решение/проект/реализация
Дык, вопрос говно. И ответ на него прост, до безобразия: понятия не имею, не смотрел даже. И это абсолютно адекватный ответ, рациональный и единственно разумный.
Хотите конструктивной дискуссии - покажите, чего такого умеет условная Krita, чего Фотошоп не умеет.
"У меня есть приложение К, в котором есть фичи А, Б и В, которых нет и не предвидится в вашем приложении Ф! Давайте обсудим, не стоит ли вам задуматься о миграции" - вот это конструктивная беседа.
А вот это ваше "у меня есть приложенька, которая почти ничем не хуже вашей, вам срочно надо мигрировать" - это не конструктивная беседа, а околофанатичный бред.
Справедливости ради, Фотошоп и Микрософтовский Эксель в своих нишах адекватной конкуренции не имеют. Но это все лирика, я бы о другом сказал.
Вот это "ну весь функционал есть, и вот крита ничуть не хуже... ну или хуже, но совсем чуть-чуть... переходите на криту"... Ну детский инфантильный лепет. Десятки тысяч людей, у которых доход напрямую зависит от инструмента X, должны все бросить и потратить миллионы человеко-часов и тонны денег на переход к использованию инструмента Y, который почти такой же и если хуже, то буквально самую малость... чтобы... А чтобы что, собственно? Заради чего сыр-бор вообще?
Даже если условный GIMP станет абсолютно таким же, как Photoshop. Вот прямо неотличимым. Что должно побудить десятки тысяч художников/фотографов/и т.д. немедленно на него перейти? В чем выгода от перехода-то?
Не показывайте "почти такие же" продукты. Показывайте те, что лучше. NGINX, Apache, Redis, Postgres, MySQL, Kafka, RabbitMQ - вот этот список можно продолжать до посинения. Это я для демонстрации того, что бал правит не открытый/проприетарный софт, а софт, имеющий конкурентные преимущества.
желающих далее взвалить на себя эту ношу не нашлось
Ну вот буквально же сами и подсвечиваете принципиальную разницу.
Свободный проект накрывается тазом в тот момент, когда никто не готов в него вложиться (что, какбэ, намекает на уровень нужности и критической важности проекта).
Проприетарный проект закрывается, когда того пожелает владелец. И в этот момент нужность и критическая важность проекта объективно идет лесом. Не важно, сколько человек готовы вложиться в поддержку и развитие проекта - они не могут, потому что продукт проприетарный.
Заметьте, я даже не ругаю "проклятых капиталистов". Элементарная ситуация "единственный автор и правообладатель программы умер от старости" приводит ровно в ситуацию невозможности дальнейшего развития продукта. Или вполне объективная причина под названием "компания закрылась", или "мы обанкротились" и т.д. и т.п. Т.е. мы не о причинах EoL говорим, не о морали или благе человечества.
Вся суть свободной лицензии в возможности развивать софт до момента истечения его объективной полезности.
И открытый код это не про “о, о, о, бесплатно!”, это про то, чтобы технологии служили и работали на благо человечества
Вот даже не рядом. Открытый и свободный код - это две категории, определяющие то, что вы с этим кодом можете делать. Ни больше, не меньше. Про благо человечества там ни слова нет.
Проприетарный софт не убивает модель открытости, а существует паралельно, предлагая рынку разную ценность.
А вот этот пассаж я что-то не понял. Проприетарный софт по самому определению проприетарности и противоречит открытости (и, тем более, свободы софта). Если даже вы открыли исходники проприетарного приложения, оно от самого этого факта ни открытым, ни свободным не стало. Что толку от кода, который вы не можете использовать?
В случае с проприетарным софтом у вас ровно один способ решения проблемы - деньги. С открытым - два (собственно те же деньги, они везде работают, плюс скилл).
В вашем вырожденным случае с dvd-навигацией вы можете либо вложиться скиллом и заполнить самому, либо деньгами, наняв того, кто запилит для вас. Ключевое отличие проприетарного софта в том, что при отказе в решении проблемы со стороны владельца софта вы никак не сможете решить проблему - ни деньгами, ни скиллом.
И не надо говорить, что это не проблема. Свободный софт и появился из решения этой проблемы - возможность поддержки софта, владелец которого не хочет его поддерживать.
Я углубился в суть. Суть вашей проблемы в 2 словах: "Go не Python". Это если коротко.
Решение еще проще: не пишите на Go как на Python'е.
Вы рисуете какие-то странные примеры с GetPersonListDTO, на которых демонстрируете билд запроса к БД и сериализацию/десериализацию в JSON.
Сразу возникает вопрос, почему сигнатура метода репозитория выглядит вот так: func (r *Repository) GetPersonList(ctx context.Context, dto GetPersonListDTO) []Person
Почему не так вот, например:
type PersonRepository interface {
GetPersonListByName(ctx context.Context, name string) ([]Person, error)
GetPersonListByNameAndPosition(ctx context.Context, name string, position string) ([]Person, error)
}
Зачем эти приседания с мутными dto'шками? Не, в Java/C#/Python понятно, зачем оно. Там ООП и всякие LINQ/EntityFramework'и/Streams и т.д. В Go всего этого нет и, вероятно, не будет в обозримом будущем. Зачем "городить огород"?
Еще более непонятно, зачем типу, описывающему запрос к БД уметь сериализоваться/десериализоваться в JSON. Тем более криво.
Вот у вас только что OptionalValue[int]{value: 0, defined: true, valid: true}, а вот мы его замаршаллили/анмаршаллили, и оно уже OptionalValue[int]{value:0, defined: false, valid: false}. Ну и зачем городили-то?
Если вы утверждаете, что ваш тип сериализацию умеет, то свою семантику при сериализации/десериализации он терять не должен.
Теперь по поводу defined/valid полей. У вас в каких случаях nil-value defined? Только если вы его сами ручками задали - все верно же? А valid оно когда? Правильно, в том же случае. А теперь объясните мне, в каком случае у вас поле определено, но не валидно, а в каких валидно, но не определено.
Короче, заранее извиняюсь, но решение - дичь, порожденная ООП головного мозга.
Вот тут по коду чуть-чуть рекомендаций себе позволю, если вы не против.
const Defined int8 = 1
В таких конструкциях лучше таки беззнаковые типы использовать.
int8 заполненный единицами в бинарном представлении - это -128 (выглядит странно, да?), а uint8 с тем же содержимым - 255.
С uint'ом открывается путь к грязным фокусам со сравнением. Например `mark > 7` вернет true, если есть хоть 1 взведенный флаг кроме первых трех. С int8 сравнение сфейлится, если будет взведен 8-й.
Вы вместо того, чтобы флаг взвести, суммируете числа. Чревато побочками, если в исходном значении не 0.
type bitmap uint8
const (
defined bitmap = 1 << iota // 1 [00000001]
valid // 2 [00000010]
accepted // 4 [00000100]
// дальше само инкрементить поразрядно будет
)
var mark = 5 // [00000101] - взведены 1 и 3 флаги
// Простые сравнения на наличие одного флага.
// В этом кейсе следующие 3 строки семантически идентичны
fmt.Println( mark & defined != 0 ) // true
fmt.Println( mark & defined > 0 ) // true
fmt.Println( mark & defined == defined ) // true
// И эти 3 сравнивают одно и то же
fmt.Println( mark & valid != 0 ) // false
fmt.Println( mark & valid > 0 ) // false
fmt.Println( mark & valid == valid ) // false
// Гораздо интереснее сравнение с несколькими флагами
// Проверяем, что все указанные флаги взведены - `mark & flags == flags`
fmt.Println(mark & (defined|valid) == defined|valid) // true, т.к. ОБА флага взведены
fmt.Println(mark & (defined|accepted) == defined|accepted) // false, т.к. взведен только ОДИН флаг.
Лучше бы предложили свое решение проблемы касаемо запросов в БД
sqlc
Или как Вы узнаете, поле было заполнено nil-ом или нет?
Зачем?
Ощущение, что Вы на go пишете просто посредственные вещи без каких-то паттернов, DRY, SOLID и прочее
Ну вот про SOLID: буковка S говорит о том, что в реализации паттерна Optional одно из полей valid/defined - лишнее.
type Optional[T any] struct {
Value T
IsSet bool
}
Все, готовый Optional. Всяческие OptionalBool и OptionalInt - не нужны, тем более в том виде, который вы использовали.
OptionalInt = OptionalType[*int]
Вот это вы зачем написали? Зачем тут указатель на int? Из принципа "что-то у меня оперативки многовато" или "а давайте посмотрим, насколько говенный у нас сборщик мусора"?
Просто вопрос: сколько памяти и где занимает ваш OptionalInt?
type Person struct {
Name string
Position *string
}
position1 := "Junior"
person1 := Pesron{Position: "Junior"} // ТУТ НЕ СКОМПИЛИРУЕТСЯ
position2 := ""
person2 := Pesron{Position: ""} // И ТУТ ТОЖЕ
person3 := Pesron{}
Ну блин, ну код-то свой запустить можно попробовать разок?
Кхм... bool-значение, занимающее 16 байт в стеке и еще 8 в куче. А может, ну его, этот ваш паттерн Optional (ну либо уже просто возьмите существующие реализации, и не парьте мозг). Ну и да, раздельные поля defined/valid нафиг не нужны (ну либо вы мне сейчас расскажете, зачем инициализировать переменную невалидным значением).
Конструктивного и по делу не написали вы.
Это вы утверждаете, что человек должен отказаться от своих привычек и посвятить свое время поискам альтернативы инструменту, который его устраивает. При этом в качестве мотивации вы продвигаете "он почти не хуже" и "мир во всем мире".
Для того, чтобы кто-то стал анализировать наличествующие альтернативы - покажите преимущества.
Человек абсолютно адекватно написал: "профитов от линя для него нет". И это ваша задача - обозначить профиты, а не его - засирать линь по надуманным поводам.
Дык, вопрос говно. И ответ на него прост, до безобразия: понятия не имею, не смотрел даже. И это абсолютно адекватный ответ, рациональный и единственно разумный.
Хотите конструктивной дискуссии - покажите, чего такого умеет условная Krita, чего Фотошоп не умеет.
"У меня есть приложение К, в котором есть фичи А, Б и В, которых нет и не предвидится в вашем приложении Ф! Давайте обсудим, не стоит ли вам задуматься о миграции" - вот это конструктивная беседа.
А вот это ваше "у меня есть приложенька, которая почти ничем не хуже вашей, вам срочно надо мигрировать" - это не конструктивная беседа, а околофанатичный бред.
Справедливости ради, Фотошоп и Микрософтовский Эксель в своих нишах адекватной конкуренции не имеют. Но это все лирика, я бы о другом сказал.
Вот это "ну весь функционал есть, и вот крита ничуть не хуже... ну или хуже, но совсем чуть-чуть... переходите на криту"... Ну детский инфантильный лепет. Десятки тысяч людей, у которых доход напрямую зависит от инструмента X, должны все бросить и потратить миллионы человеко-часов и тонны денег на переход к использованию инструмента Y, который почти такой же и если хуже, то буквально самую малость... чтобы... А чтобы что, собственно? Заради чего сыр-бор вообще?
Даже если условный GIMP станет абсолютно таким же, как Photoshop. Вот прямо неотличимым. Что должно побудить десятки тысяч художников/фотографов/и т.д. немедленно на него перейти? В чем выгода от перехода-то?
Не показывайте "почти такие же" продукты. Показывайте те, что лучше. NGINX, Apache, Redis, Postgres, MySQL, Kafka, RabbitMQ - вот этот список можно продолжать до посинения. Это я для демонстрации того, что бал правит не открытый/проприетарный софт, а софт, имеющий конкурентные преимущества.
Ну вот буквально же сами и подсвечиваете принципиальную разницу.
Свободный проект накрывается тазом в тот момент, когда никто не готов в него вложиться (что, какбэ, намекает на уровень нужности и критической важности проекта).
Проприетарный проект закрывается, когда того пожелает владелец. И в этот момент нужность и критическая важность проекта объективно идет лесом. Не важно, сколько человек готовы вложиться в поддержку и развитие проекта - они не могут, потому что продукт проприетарный.
Заметьте, я даже не ругаю "проклятых капиталистов". Элементарная ситуация "единственный автор и правообладатель программы умер от старости" приводит ровно в ситуацию невозможности дальнейшего развития продукта. Или вполне объективная причина под названием "компания закрылась", или "мы обанкротились" и т.д. и т.п. Т.е. мы не о причинах EoL говорим, не о морали или благе человечества.
Вся суть свободной лицензии в возможности развивать софт до момента истечения его объективной полезности.
А "все остальные" тут откуда нарисовалась?
Вот даже не рядом. Открытый и свободный код - это две категории, определяющие то, что вы с этим кодом можете делать. Ни больше, не меньше. Про благо человечества там ни слова нет.
А вот этот пассаж я что-то не понял. Проприетарный софт по самому определению проприетарности и противоречит открытости (и, тем более, свободы софта). Если даже вы открыли исходники проприетарного приложения, оно от самого этого факта ни открытым, ни свободным не стало. Что толку от кода, который вы не можете использовать?
Какое-то когнитивное искажение.
В случае с проприетарным софтом у вас ровно один способ решения проблемы - деньги. С открытым - два (собственно те же деньги, они везде работают, плюс скилл).
В вашем вырожденным случае с dvd-навигацией вы можете либо вложиться скиллом и заполнить самому, либо деньгами, наняв того, кто запилит для вас. Ключевое отличие проприетарного софта в том, что при отказе в решении проблемы со стороны владельца софта вы никак не сможете решить проблему - ни деньгами, ни скиллом.
И не надо говорить, что это не проблема. Свободный софт и появился из решения этой проблемы - возможность поддержки софта, владелец которого не хочет его поддерживать.
Ответы на вопросы в порядке поступления порядку:
В статье
В фантазиях
Выдуманный
Но выглядит как поток сознания.
Долго упаковать, что ли?
Ну тут, имхо, стоит чинить приемы генерации корпоративной отчётности...
Ребят, ну вы чо. Просто невалидная жсонка же:
Data/consumer/rank - тут вложенная структура с полем sub.
А дальше вот эта штука {"code":"C"} вообще родительского узла не имеет. Т.е. rank должен либо массивом быть, либо структурой с полями sub и code
Я углубился в суть. Суть вашей проблемы в 2 словах: "Go не Python". Это если коротко.
Решение еще проще: не пишите на Go как на Python'е.
Вы рисуете какие-то странные примеры с GetPersonListDTO, на которых демонстрируете билд запроса к БД и сериализацию/десериализацию в JSON.
Сразу возникает вопрос, почему сигнатура метода репозитория выглядит вот так:
func (r *Repository) GetPersonList(ctx context.Context, dto GetPersonListDTO) []Person
Почему не так вот, например:
Зачем эти приседания с мутными dto'шками? Не, в Java/C#/Python понятно, зачем оно. Там ООП и всякие LINQ/EntityFramework'и/Streams и т.д. В Go всего этого нет и, вероятно, не будет в обозримом будущем. Зачем "городить огород"?
Еще более непонятно, зачем типу, описывающему запрос к БД уметь сериализоваться/десериализоваться в JSON. Тем более криво.
Вот у вас только что OptionalValue[int]{value: 0, defined: true, valid: true}, а вот мы его замаршаллили/анмаршаллили, и оно уже OptionalValue[int]{value:0, defined: false, valid: false}. Ну и зачем городили-то?
Если вы утверждаете, что ваш тип сериализацию умеет, то свою семантику при сериализации/десериализации он терять не должен.
Теперь по поводу defined/valid полей. У вас в каких случаях nil-value defined? Только если вы его сами ручками задали - все верно же? А valid оно когда? Правильно, в том же случае. А теперь объясните мне, в каком случае у вас поле определено, но не валидно, а в каких валидно, но не определено.
Короче, заранее извиняюсь, но решение - дичь, порожденная ООП головного мозга.
Вот тут по коду чуть-чуть рекомендаций себе позволю, если вы не против.
const Defined int8 = 1
В таких конструкциях лучше таки беззнаковые типы использовать.
int8 заполненный единицами в бинарном представлении - это -128 (выглядит странно, да?), а uint8 с тем же содержимым - 255.
С uint'ом открывается путь к грязным фокусам со сравнением. Например `mark > 7` вернет true, если есть хоть 1 взведенный флаг кроме первых трех. С int8 сравнение сфейлится, если будет взведен 8-й.
Вот тут однозначно Mark = Mark|Valid.
Вы вместо того, чтобы флаг взвести, суммируете числа. Чревато побочками, если в исходном значении не 0.
И эти люди...
Ну т.е. не расскажете...
sqlc
Зачем?
Ну вот про SOLID: буковка S говорит о том, что в реализации паттерна Optional одно из полей valid/defined - лишнее.
Все, готовый Optional. Всяческие OptionalBool и OptionalInt - не нужны, тем более в том виде, который вы использовали.
OptionalInt = OptionalType[*int]
Вот это вы зачем написали? Зачем тут указатель на int? Из принципа "что-то у меня оперативки многовато" или "а давайте посмотрим, насколько говенный у нас сборщик мусора"?
Просто вопрос: сколько памяти и где занимает ваш OptionalInt?
Ну блин, ну код-то свой запустить можно попробовать разок?
Ну и "библиотеку" посмотрел:
Кхм... bool-значение, занимающее 16 байт в стеке и еще 8 в куче. А может, ну его, этот ваш паттерн Optional (ну либо уже просто возьмите существующие реализации, и не парьте мозг). Ну и да, раздельные поля defined/valid нафиг не нужны (ну либо вы мне сейчас расскажете, зачем инициализировать переменную невалидным значением).
Просто интереса ради: а зачем несколько сквозных нумераций?
Да блин куда уж точнее: "проектов по управлению балансами банковских счетов"
Управление балансами (читай, изменение циферки на счету) банковских счетов.
Ну ок, сократим формулировка: банковские транзакции.