0Pricing
Go Academy · Lekcja

Dynamiczne ładowanie i symbole

Ładowanie pluginów w czasie działania i wywoływanie eksportowanych symboli

Dynamiczne ładowanie i symbole to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

plugin.Open

plugin.Open(path) ładuje skompilowany plik .so. Inicjalizuje funkcje init() pluginu i zmienne na poziomie pakietu, a następnie udostępnia symbole.

p, err := plugin.Open("./plugins/mymodule.so")
if err != nil { log.Fatalf("load: %v", err) }

p.Lookup

p.Lookup(name) wyszukuje eksportowany symbol według nazwy. Zwraca wartość typu any; należy wykonać asercję typu do oczekiwanego typu.

sym, err := p.Lookup("NewProcessor")
if err != nil { log.Fatalf("lookup: %v", err) }
fn, ok := sym.(func() Processor)
if !ok { log.Fatal("wrong type") }

Ładowanie wielu pluginów

Każdy plik .so należy załadować z katalogu i zarejestrować w pętli:

entries, _ := os.ReadDir("./plugins")
for _, e := range entries {
    if !strings.HasSuffix(e.Name(), ".so") { continue }
    p, err := plugin.Open("./plugins/" + e.Name())
    if err != nil { log.Printf("skip %s: %v", e.Name(), err); continue }
    loadPlugin(p)
}

Wzorzec funkcji fabrykującej

Pluginy eksportują funkcję fabrykującą (NewXxx() Processor) zamiast wartości, dzięki czemu host otrzymuje nową instancję przy każdym wywołaniu:

sym, _ := p.Lookup("NewProcessor")
factory := sym.(func() Processor)
proc := factory() // new instance

Obsługa błędów podczas wyszukiwania

Błędy Lookup oznaczają, że symbol nie jest eksportowany lub jego nazwa jest nieprawidłowa. Należy obsłużyć je w kontrolowany sposób — pominąć plugin albo zapisać błąd w logu i kontynuować ładowanie pozostałych.

plugin.Open jest idempotentne

Dwukrotne wywołanie plugin.Open dla tej samej ścieżki zwraca ten sam plugin. Plugin jest inicjalizowany tylko raz.

Ładowanie leniwe

Pluginy należy ładować na żądanie (przy pierwszym użyciu), a nie podczas uruchamiania, aby skrócić czas startu. Dla każdego pluginu należy użyć sync.Once, aby zapewnić jego dokładne jednokrotne załadowanie.

var mu sync.Mutex
var loaded = map[string]*plugin.Plugin{}

func getPlugin(path string) (*plugin.Plugin, error) {
    mu.Lock(); defer mu.Unlock()
    if p, ok := loaded[path]; ok { return p, nil }
    p, err := plugin.Open(path)
    if err != nil { return nil, err }
    loaded[path] = p
    return p, nil
}

Konwencje nazewnictwa symboli

Eksportowane symbole powinny mieć nazwy w konwencji CamelCase zaczynające się wielką literą (obowiązuje reguła widoczności Go). Typowa konwencja to Plugin dla głównej wartości lub New dla funkcji fabrykującej.

Obsługa panik pluginów

Jeśli plugin zgłosi panikę, middleware recover hosta może ją przechwycić, ale goroutines pluginu mogą znaleźć się w niezdefiniowanym stanie. Należy zapisać błąd w logu i pominąć plugin; nie należy ponawiać próby.

Weryfikowanie metadanych pluginu

Po załadowaniu należy sprawdzić symbol metadanych (np. PluginVersion string), aby zweryfikować zgodność przed zarejestrowaniem:

ver, _ := p.Lookup("PluginVersion")
if *ver.(*string) != expectedVersion { log.Fatal("incompatible") }

Szybkie sprawdzenie

Co się stanie, jeśli wywoła Pan/Pani plugin.Open dwukrotnie z tą samą ścieżką?

Podsumowanie: ładowanie dynamiczne i symbole

Najważniejsze informacje:

  • plugin.Open ładuje plik .so; p.Lookup zwraca any → należy wykonać asercję typu
  • Ładować pluginy z katalogu w pętli, aby utworzyć system pluginów
  • plugin.Open jest idempotentne; init() jest uruchamiane raz dla każdej ścieżki
  • Należy preferować funkcje fabrykujące zamiast symboli wartości, aby uzyskiwać nowe instancje

Często zadawane pytania

Czy lekcja „Dynamiczne ładowanie i symbole” jest bezpłatna?

Tak — pełny tekst „Dynamiczne ładowanie i symbole” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Dynamiczne ładowanie i symbole”?

Ładowanie pluginów w czasie działania i wywoływanie eksportowanych symboli Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Dynamiczne ładowanie i symbole”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Podstawy pakietu plugin w Go
  2. Projektowanie interfejsu pluginu
  3. Dynamiczne ładowanie i symbole
  4. Alternatywy: HashiCorp go-plugin
← Powrót do Go Academy