Dans Go 1.8, les plugins peuvent utiliser des interfaces personnalisées. Cependant, il y a certaines limites à prendre en compte.
Une approche consiste à définir l'interface dans un package externe et à la faire importer à la fois par le plugin et l'application principale.
Par exemple, créez une interface dans un package appelé filter :
package filter type Filter interface { Name() string Age() int }
Dans le plugin, importez le package filter et implémentez le interface :
package main import ( "fmt" "filter" ) type plgFilter struct{} func (plgFilter) Name() string { return "Bob" } func (plgFilter) Age() int { return 23 } func GetFilter() (f filter.Filter, err error) { f = plgFilter{} fmt.Printf("[plugin GetFilter] Returning filter: %T %v\n", f, f) return }
Dans l'application principale, importez le package de filtre et chargez le plugin :
package main import ( "fmt" "filter" "plugin" ) func main() { p, err := plugin.Open("pg/pg.so") if err != nil { panic(err) } GetFilter, err := p.Lookup("GetFilter") if err != nil { panic(err) } filter, err := GetFilter.(func() (filter.Filter, error))() fmt.Printf("GetFilter result: %T %v %v\n", filter, filter, err) fmt.Println("\tName:", filter.Name()) fmt.Println("\tAge:", filter.Age()) }
Cette approche garantit que le plugin a accès à la définition de l'interface.
Une autre option consiste à ce que le plugin renvoie une valeur de type interface{}. L'application principale peut alors définir l'interface qu'elle attend et utiliser l'assertion de type sur la valeur renvoyée.
Par exemple, dans le plugin :
package main import ( "fmt" ) type plgFilter struct{} func (plgFilter) Name() string { return "Bob" } func (plgFilter) Age() int { return 23 } func GetFilterIface() (f interface{}, err error) { f = plgFilter{} fmt.Printf("[plugin GetFilterIface] Returning filter: %T %v\n", f, f) return }
Dans l'application principale :
package main import ( "fmt" "plugin" ) func main() { p, err := plugin.Open("pg/pg.so") if err != nil { panic(err) } GetFilterIface, err := p.Lookup("GetFilterIface") if err != nil { panic(err) } filterIface, err := GetFilterIface.(func() (interface{}, error))() fmt.Printf("GetFilterIface result: %T %v %v\n", filterIface, filterIface, err) myfilter := filterIface.(MyFilter) fmt.Println("\tName:", myfilter.Name()) fmt.Println("\tAge:", myfilter.Age()) } type MyFilter interface { Name() string Age() int }
Cette approche offre plus de flexibilité, mais nécessite essentiellement une assertion de type application.
Notez que les interfaces personnalisées ne fonctionnent que si l'interface est définie en dehors du plugin. En effet, les plugins Go sont des modules autonomes qui ne peuvent pas accéder aux types définis dans d'autres packages.
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!