Home >Backend Development >Golang >## Can You Type Assert Custom Data Structures in Go Plugins?

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

Barbara Streisand
Barbara StreisandOriginal
2024-10-29 14:14:02896browse

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

Custom Data Type Sharing Between Go Plugin and Application

In Go, it's possible to share data between a plugin and an application. However, the question arises whether it's feasible to type assert into a custom data structure as opposed to an interface.

Type Assertion with Custom Structures

Consider this scenario:

<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>

When attempting to type assert the symbol P to a Person in the app.go file, you'll encounter an execution time error: "Wrong symbol type."

Solution: Common Type Package

To overcome this limitation, define the custom data type in a separate package and use it in both the plugin and the main application.

<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>

In this example, the Filter type is defined in a separate package, making it accessible to both the plugin and the main application. As a result, type assertion from the plugin's symbol to a *filter.Filter succeeds.

Note that:

  • Variables defined in the main package cannot be referred to from other packages, so avoid using the same type in the plugin and the main application directly.
  • Symbols representing variables are returned as pointers, allowing you to modify their values.
  • Functions returning values of non-pointer type can be looked up with a function pointer.
  • Changing the common type package requires rebuilding the plugin.

The above is the detailed content of ## Can You Type Assert Custom Data Structures in Go Plugins?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn