Go Academy · leksjon

Dynamiske funksjonskall

Kalle funksjoner og angi verdier via reflect

Leksjon 3 av 413 trinn

Dynamiske funksjonskall er en gratis leksjon i Go Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Go Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Go Academy inneholder totalt 4 leksjoner.

reflect.Value.Call

Value.Call(args) kaller funksjonen som representeres av Value, med de angitte argumentene (som en []reflect.Value), og returnerer resultatene som en []reflect.Value.

fn := reflect.ValueOf(add)
results := fn.Call([]reflect.Value{
    reflect.ValueOf(2),
    reflect.ValueOf(3),
})
fmt.Println(results[0].Int()) // 5

Kontrollere argumenttyper

Kontroller at argumenttypene samsvarer med funksjonssignaturen før kallet. Typer som ikke samsvarer, utløser en panic.

t := reflect.TypeOf(fn)
if t.NumIn() != len(args) { panic("wrong arg count") }
for i, arg := range args {
    if !reflect.TypeOf(arg).AssignableTo(t.In(i)) { panic("type mismatch") }
}

Variadiske funksjoner

Kall en variadisk funksjon med Value.Call (ved å spre slice-en) eller Value.CallSlice (ved å sende de variadiske argumentene som en slice-verdi):

sum := reflect.ValueOf(func(ns ...int) int {
    total := 0
    for _, n := range ns { total += n }
    return total
})
args := reflect.ValueOf([]int{1,2,3})
results := sum.CallSlice([]reflect.Value{args})

reflect.MakeFunc

reflect.MakeFunc oppretter en ny funksjon under kjøring med en angitt type og en wrapper-kropp. Den brukes til å generere adapterfunksjoner for grensesnitt.

t := reflect.TypeOf(func(int) string { return "" })
fn := reflect.MakeFunc(t, func(args []reflect.Value) []reflect.Value {
    return []reflect.Value{reflect.ValueOf(strconv.Itoa(args[0].Interface().(int)))}
})

Kalle metoder etter navn

Hent en metode etter navn, og kall den:

v := reflect.ValueOf(myObj)
m := v.MethodByName("Process")
if m.IsValid() {
    m.Call(nil)
}

Kontrollere om en metode finnes

Kontroller alltid m.IsValid() før kallet – MethodByName returnerer nullverdien hvis metoden ikke ble funnet, og et kall på nullverdien utløser en panic.

Bruksområder for dynamisk dispatch

Dynamiske funksjonskall brukes i: plugin-systemer (kalle funksjoner etter strengnavn), testrammeverk (kalle TestXxx-funksjoner), RPC-dispatchere (koble metodenavn til handlere) og dekoratorer.

Ytelse

reflect.Call er omtrent 10–50× tregere enn et direkte kall. Bufre reflect.Value for funksjoner som kalles ofte, og unngå dem i løkker som kjøres ofte.

Typesikker wrapper

Pakk dynamiske kall inn i en typet hjelpefunksjon som utfører reflection-mekanismen én gang under oppstart, og kaller den bufrede Value-en gjentatte ganger:

type Processor func(context.Context, []byte) ([]byte, error)
// Build at startup, reuse at request time

Håndtere returverdier av typen error

Hvis funksjonen returnerer en error som sitt siste resultat, må De hente den ut og kontrollere den:

results := fn.Call(args)
if !results[len(results)-1].IsNil() {
    return results[len(results)-1].Interface().(error)
}

Alternativer til reflection

Hvis funksjonssettet er kjent ved kompilering, bør De bruke et kart med funksjonsverdier (map[string]func(...)) i stedet for reflection – det er sikrere og raskere.

handlers := map[string]func(ctx context.Context, req []byte) []byte{
    "greet": greetHandler,
}

Hurtigsjekk

Hva returnerer reflect.Value.Call?

Oppsummering: Dynamiske funksjonskall

Viktige punkter:

  • Value.Call([]reflect.Value) kaller funksjonen og returnerer []reflect.Value
  • Kontroller m.IsValid() før De kaller resultatet fra MethodByName
  • MakeFunc oppretter en ny funksjon med en angitt type under kjøring
  • Foretrekk map[string]func fremfor reflection for kjente funksjonssett
Gratis å komme i gang

Lær deg Go med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
51
Leksjoner
203

Ofte stilte spørsmål

Er leksjonen «Dynamiske funksjonskall» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Go Academy, inkludert «Dynamiske funksjonskall», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Go Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Dynamiske funksjonskall»?

Kalle funksjoner og angi verdier via reflect Du øver på Go Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Go Academy?

Ingen tidligere erfaring er nødvendig. Go Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Dynamiske funksjonskall»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Go Academy-leksjonen?

Ja. Alle Go Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. reflect.Type og reflect.Value
  2. Inspisere struct-felter og tags
  3. Dynamiske funksjonskall
  4. Praktisk refleksjon: serialiserere
← Tilbake til Go Academy