Sobes.tech
Middle+

Jakie są sposoby pisania ogólnego kodu w Go?

sobes.tech AI

Odpowiedź od AI

W języku Go przedstawiono następujące główne sposoby pisania kodu generycznego:

  • Interfejsy: Pozwalają pisać funkcje, które działają z dowolnymi typami spełniającymi określony zestaw metod.

    // Definicja interfejsu Reader
    type Reader interface {
        Read(p []byte) (n int, err error)
    }
    
    // Funkcja działająca z dowolnym typem implementującym Reader
    func ProcessData(r Reader) error {
        // odczyt danych z Reader
        return nil
    }
    
  • Pusty interfejs (interface{}): Uniwersalny typ, który może reprezentować dowolną wartość. Wymaga rzutowania typu przed użyciem.

    func PrintAnything(v interface{}) {
        // Rzutowanie typu z sprawdzeniem
        if s, ok := v.(string); ok {
            fmt.Println("To jest łańcuch:", s)
        } else if i, ok := v.(int); ok {
            fmt.Println("To jest liczba całkowita:", i)
        }
    }
    
  • Generics / Typy parametryzowane (type parameters): Pozwalają pisać funkcje i typy, które działają z dowolnymi zestawami typów, określonymi podczas deklaracji. Dodane w Go 1.18.

    // Funkcja działająca z tablicami dowolnego typu T
    func PrintSlice[T any](s []T) {
        for _, v := range s {
            fmt.Println(v)
        }
    }
    
    // Ogólny typ Pair z parametrami T1 i T2
    type Pair[T1, T2 any] struct {
        First T1
        Second T2
    }
    
  • Refleksja (reflect): Pozwala na badanie i interakcję z typami i wartościami podczas wykonywania. Często używana w skomplikowanych scenariuszach, ale może być mniej wydajna i bezpieczna niż inne podejścia.

    import "reflect"
    
    func GetTypeName(v interface{}) string {
        return reflect.TypeOf(v).Name()
    }
    

Wybór metody zależy od konkretnego zadania i wymaganego poziomu elastyczności i wydajności. Generics są preferowaną metodą do tworzenia ogólnych algorytmów i struktur danych we współczesnym Go. Interfejsy pozostają kluczowym mechanizmem dla polimorfizmu i określania zachowania. Pusty interfejs i refleksja są rzadziej używane, w bardziej specyficznych przypadkach.