Maison >développement back-end >Golang >## Pouvez-vous saisir des structures de données personnalisées dans les plugins Go ?

## Pouvez-vous saisir des structures de données personnalisées dans les plugins Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-29 14:14:02927parcourir

## Can You Type Assert Custom Data Structures in Go Plugins?

Partage de types de données personnalisés entre le plugin Go et l'application

Dans Go, il est possible de partager des données entre un plugin et une application. Cependant, la question se pose de savoir s'il est possible de taper assert dans une structure de données personnalisée plutôt que dans une interface.

Assertion de type avec des structures personnalisées

Considérez ce scénario :

<code class="go">// plugin.go
package main

type Person struct {
    Name string
}

var (
    P = Person{
        Name: "Emma",
    }
)</code>
<code class="go">// app.go
package main

import (
    "fmt"
    "plugin"
    "os"
)

func main() {
    plug, err := plugin.Open("./plugin.so")
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    sym, err := plug.Lookup("P")
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    var p Person
    p, ok := sym.(Person)
    if !ok {
        fmt.Println("Wrong symbol type")
        os.Exit(1)
    }

    fmt.Println(p.Name)
}</code>

Lorsque vous essayez de saisir le symbole P auprès d'une personne dans le fichier app.go, vous rencontrerez une erreur de temps d'exécution : "Type de symbole incorrect."

Solution : Package de type commun

Pour surmonter cette limitation, définissez le type de données personnalisé dans un package séparé et utilisez-le à la fois dans le plugin et dans l'application principale.

<code class="go">// filter/filter.go
package filter

type Filter struct {
    Name string
    Age  int
}</code>
<code class="go">// plugin/main.go
package main

import (
    "play/filter"
)

var MyFilter = filter.Filter{
    Name: "Bob",
    Age:  21,
}

func CreateFilter() filter.Filter {
    return filter.Filter{
        Name: "Bob",
        Age:  21,
    }
}</code>
<code class="go">// app/main.go
package main

import (
    "fmt"
    "log"
    "os"
    "play/filter"
    "plugin"
)

func main() {
    p, err := plugin.Open("plugin.so")
    if err != nil {
        log.Fatal(err)
    }
    mf, err := p.Lookup("MyFilter")
    if err != nil {
        log.Fatal(err)
    }
    f, ok := mf.(*filter.Filter)
    if !ok {
        log.Fatal("Wrong symbol type")
    }

    fmt.Printf("%+v\n", f)
}</code>

Dans cet exemple, le type Filter est défini dans un package séparé, le rendant accessible à la fois au plugin et à l'application principale. En conséquence, tapez l'assertion du symbole du plugin vers un *filter.Filter réussit.

Notez que :

  • Les variables définies dans le package principal ne peuvent pas être référencées à partir d'autres packages, évitez donc d'utiliser le même type dans le plugin et l'application principale directement.
  • Les symboles représentant les variables sont renvoyés sous forme de pointeurs, vous permettant de modifier leurs valeurs.
  • Fonctions renvoyant des valeurs de type non-pointeur peut être recherché avec un pointeur de fonction.
  • La modification du package de type commun nécessite la reconstruction du plugin.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn