Search
Write a publication
Pull to refresh

Comments 7

Я считаю что явное лучше неявного

type ItemText struct {
  Content string `json:"content"`
}

type ItemImage struct {
  URL string `json:"url"`
}

type Items struct {
  Texts  []ItemText  `json:"texts,omitempty"`
  Images []ItemImage `json:"images,omitempty"`
}

Явное, конечно, лучше, но это уже совсем другая структура. Возможно, нужно было использовать другой пример, что-то такое:

type IsAction interface {
	IsAction()
}

type ActionAlert struct{
	Text string `json:"text"`
}

func (ActionAlert) IsAction() {}

type ActionDeepLink struct {
	URL string `json:"url"`
}

func (ActionDeepLink) IsAction() {}

type Button struct {
	Text string
	Type string
	Action Action // HERE
}

Button является уже зафиксированым контрактом и нужно работать с JSON вида:

{
	"text": "Click me",
	"type": "primary",
	"action": {
		"text": "It's an alert!"
	}
}

Вот почему они в Go не добавили алгебраические типы данных? Это же блин как без одной руки жить. Можно но неудобно.

Да, про это даже есть вопрос в FAQ: https://go.dev/doc/faq#variant_types

Если коротко: хотели, но решили, что пересекается с интерфейсами, может путать.

Мне кажется, что сериализация/десериализация должна быть отделена от логики программы в тот самый момент когда JSON не ложится на структуру из бизнес-логики как масло на хлеб.

Поэтому было бы лучше десериализовать JSON в простую структуру с базовыми типами, а потом преобразовать эту структуру в структуру, использующуюся в бизнес-логике.

И тогда вы будете явно видеть, что происходит, даже 5 лет спустя. И не будете ломать голову о "магию" полиморфизма

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

Что же до магии, то когда вы имеете дело с двумя такими структурами по три варианта, то да, — можно и без этого всего, но с Marshaler/Unmarshaler: так будет легче разобраться. Но когда доходит до десятков, то оказывается куда легче разобраться в библиотечной магии, чем в таком количестве пусть и явных, но чрезмерно многословных преобразователях. В конечном счёте вы всё равно сделаете десяток своих хелперов, в которых тоже нужно будет разбираться; и не исключено, что они покажутся почти такими же магическими.

Десяток хелперов не окажется магическим, потому что адаптер у вас будет всё равно один на одну сущность. А внутри него будет явная, хорошо читаемая и стройная логика выбора.

Я не отрицаю, что работа с JSON в Go в текущем виде далека от идеала, но это, ПО-МОЕМУ, всё равно лучше магии. Я ведь, собственно, и перешёл в Go по причине того, что мне страсть как надоело сражаться с магическим библиотеками когда надо хоть чуточку отойти от их специфических догм. Когда я увидел, что сообщество Go терпеть не может ORM, меня невозможно стало остановить.

Есть же ещё одно не очень очевидное преимущество: LLM будет лучше понимать простой код, чем сложную магию библиотеки, которая предусматривает не конкретные случаи, а всё на свете. Как минимум, контекст сэкономите)

Sign up to leave a comment.

Articles