In Go 1.8, plugins can use custom interfaces. However, there are some limitations to consider.
One approach is to define the interface in an external package and have both the plugin and the main application import it.
For example, create an interface in a package called filter:
package filter type Filter interface { Name() string Age() int }
In the plugin, import the filter package and implement the 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 }
In the main application, import the filter package and load the 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()) }
This approach ensures that the plugin has access to the interface definition.
Another option is to have the plugin return a value of type interface{}. The main application can then define the interface it expects and use type assertion on the returned value.
For example, in the 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 }
In the main application:
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 }
This approach provides more flexibility, but requires type assertion in the main application.
Note that custom interfaces work only if the interface is defined outside of the plugin. This is because Go plugins are self-contained modules that cannot access types defined in other packages.
The above is the detailed content of How Can I Use Custom Interfaces with Go 1.8 Plugins?. For more information, please follow other related articles on the PHP Chinese website!