Можно ли создать коллекцию, содержащую элементы разных типов?

<pre><code class="go">func foo(value int) int     { return value }
  • 24 февраля 2026 г. 14:02
Ответы на вопрос 2
Коротко — да, можно. В Go коллекция (слайс, массив, map и т.д.) по умолчанию однородна по типу элементов, но вы можете сделать её «гетерогенной», используя общий интерфейс, обычно пустой интерфейс interface{} (в Go1.18+ — алиас any).

Примеры.

1) Слайс различных значений через any/interface{}:
```go
package main

import "fmt"

func foo(value int) int { return value }

func main() {
    col := []any{1, "two", 3.14, foo}

    for _, v := range col {
        switch t := v.(type) {
        case int:
            fmt.Println("int:", t)
        case string:
            fmt.Println("string:", t)
        case float64:
            fmt.Println("float64:", t)
        case func(int) int:
            fmt.Println("func result:", t(5))
        default:
            fmt.Printf("unknown: %T\n", v)
        }
    }
}
```
При извлечении значений нужно делать приведение типов (type assertion) или type switch.

2) map[string]any для JSON-подобных структур:
```go
m := map[string]any{
    "id":   123,
    "name": "Alice",
    "tags": []any{"go", "programming"},
}
```

3) Предпочтительный способ для полиморфизма — общий интерфейс с методами:
```go
type Speaker interface {
    Speak() string
}

type Dog struct{}
func (Dog) Speak() string { return "woof" }

type Cat struct{}
func (Cat) Speak() string { return "meow" }

arr := []Speaker{Dog{}, Cat{}}
```
Так вы сохраняете типобезопасность и не нуждаетесь в приведениях, если вам важна общая поведение.

4) Generics (Go 1.18+) не дают «встроенного» способа хранить в одной коллекции разные типы одновременно, если только вы не выберете обобщённый параметр как интерфейс (например any) или интерфейс-объединение типов. Например, type Slice[T any] []T — при инстанциации T фиксируется, поэтому все элементы будут одного конкретного T.

Итого:
- Да, можно через interface{}/any или через интерфейс с методами.
- Минус interface{} — теряется проверка типов на этапе компиляции, нужны приведения/type switch.
- Лучше проектировать API с общим интерфейсом или с корректной структурой данных, вместо широкого использования any, если вам важна безопасность типов.
Можно так <code class="go">funcs := []any{foo, bar}</code> Только потом нужно использовать type assertion <code class="go">f, ok := element.(func(int) int)</code>
Похожие вопросы