Существует несколько способов написания обобщенного кода. До выхода Go 1.18, который представил встроенную поддержку обобщений (generics), разработчики использовали различные техники для достижения аналогичного эффекта.
С выходом Go 1.18 язык получил встроенную поддержку обобщений, позволяющую создавать обобщенные функции и типы. Это позволяет писать код, который работает с любыми типами, определенными параметрами.
package main
import "fmt"
func Map[T any](arr []T, f func(T) T) []T {
result := make([]T, len(arr))
for i, v := range arr {
result[i] = f(v)
}
return result
}
func main() {
nums := []int{1, 2, 3, 4}
doubled := Map(nums, func(n int) int { return n * 2 })
fmt.Println(doubled) // [2, 4, 6, 8]
}
Пример обобщенного типа:
package main
import "fmt"
type Pair[T any, U any] struct {
First T
Second U
}
func main() {
p := Pair[int, string]{First: 1, Second: "one"}
fmt.Println(p) // {1 one}
}
До появления обобщений, интерфейсы были основным способом достижения обобщенности. Интерфейсы позволяют определять функции, которые могут работать с любыми типами, реализующими определенные методы.
package main
import "fmt"
type Stringer interface {
String() string
}
func Print(s Stringer) {
fmt.Println(s.String())
}
type Person struct {
Name string
}
func (p Person) String() string {
return p.Name
}
func main() {
p := Person{Name: "Alice"}
Print(p) // Alice
}
Пустой интерфейс (
interface{}
) может содержать значения любого типа. Это позволяет создавать функции, принимающие значения любых типов, но требует явного приведения типов.package main
import "fmt"
func Print(v interface{}) {
fmt.Println(v)
}
func main() {
Print(42)
Print("Hello")
Print([]int{1, 2, 3})
}
Рефлексия позволяет программам исследовать и изменять структуру и поведение объектов во время выполнения. Это мощный, но сложный способ написания обобщенного кода.
package main
import (
"fmt"
"reflect"
)
func Print(v interface{}) {
rv := reflect.ValueOf(v)
fmt.Println("Type:", rv.Type(), "Value:", rv)
}
func main() {
Print(42) // Type: int Value: 42
Print("Hello") // Type: string Value: Hello
Print([]int{1, 2, 3}) // Type: []int Value: [1 2 3]
}
Ставь 👍 и забирай 📚 Базу знаний