Я работаю над несколькими проектами веб-сервера в Go, и есть общая проблема, с которой я всегда сталкиваюсь. Я знаю, что мы можем достичь чего-то вроде полиморфизма в Go с помощью интерфейсов и методов, но много раз у меня был сценарий, когда мне требовался полиморфизм для некоторых структур держателей данных, которые (возможно) просто имели некоторые общие поля и вообще не имели методов.
Например, рассмотрим платформу для написания историй, где каждый пользователь может писать короткие рассказы и романы:
type ShortStory struct {
Name string
ID int
Body string
}
type LongStory struct {
Name string
ID int
Chapters []string
}
Теперь я просто хочу иметь функцию слоя данных, скажем GetStories()
, которая извлекает все истории, написанные пользователем, из базы данных.
func GetStories(id int) []SOME_TYPE {
...
}
На самом деле нет никаких методов, которые я бы хотел использовать в своих структурах ShortStory
и LongStory
. Я знаю, что могу добавить фиктивный метод и позволить им удовлетворить некоторый интерфейс Storier
, а затем использовать этот интерфейс в качестве возвращаемого типа. Но так как в модели контейнера данных я не хотел бы использовать какой-либо метод, добавление фиктивного метода только для того, чтобы язык включал функцию, кажется мне неудачным выбором при проектировании.
Я также могу сделать возврат функции []interface{}
, но я полагаю, что это противоречит самой идее "типизированного языка".
Другой способ - использовать два отдельных метода GetShortStories()
и GetLongStories()
, которые возвращают фрагмент своего собственного типа. Но в какой-то момент я, наконец, хотел бы объединить эти два фрагмента в один, и там мне снова понадобится []interface{}
. Да, я могу вернуть JSON как:
{
"short_stories" : [...],
"long_stories" : [...]
}
Но я хочу, чтобы мой json был похож на:
[{...}, {...}, {...}]
И я бы не стал менять свои API из-за ограничения языка!
Я не профессионал в Go, поэтому я что-то здесь упускаю? Есть ли Go -i sh подход к этому или действительно плохой языковой дизайн на стороне Golang?