1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Go 插件功能的實(shí)現(xiàn)方式

        共 3524字,需瀏覽 8分鐘

         ·

        2021-09-02 20:31

        官方實(shí)現(xiàn)

        golang 1.8 及以上版本提供了一個(gè)創(chuàng)建共享庫(shared object)的新工具,稱為 Plugins。目前 Plugins 僅在 Linux、FreeBSD 和 macOS 上受支持,且只支持 golang 調(diào)用。

        使用示例,定義一個(gè) plugin.go

        package main

        import (
         "log"
        )

        func init() {
         log.Println("plugin init")
        }

        type SayHello struct {
        }

        func (s *SayHello) CallMe(name string) string {
         log.Println("hello ", name)
         return "I am plugin"
        }

        // SayHelloPlugin 導(dǎo)出變量
        var SayHelloPlugin SayHello

        使用 -buildmode=plugin 模式編譯出 plugin.so 共享庫

        go build -o plugin.so -buildmode=plugin plugin.go

        main.go 中調(diào)用插件:

        package main

        import (
         "log"
         "plugin"
        )

        type CustomPlugin interface {
         CallMe(name stringstring
        }

        func main() {
         // 打開插件(并發(fā)安全)
         p, err := plugin.Open("plugin.so")
         if err != nil {
          panic(err)
         }
         // 在插件中搜索可導(dǎo)出的變量或函數(shù)
         sayHelloPlugin, err := p.Lookup("SayHelloPlugin")
         if err != nil {
          panic(err)
         }
         // 斷言插件類型
         if sayHello, ok := sayHelloPlugin.(CustomPlugin); ok {
          log.Println(sayHello.CallMe("togettoyou"))
         }
        }
        go run main.go

        # 輸出
        2021/07/28 17:07:21 plugin init
        2021/07/28 17:07:21 hello  togettoyou
        2021/07/28 17:07:21 I am plugin

        定義一個(gè)插件總結(jié):

        • package 包名需要定義為 main
        • 必須有可導(dǎo)出的變量或函數(shù)
        • 不需要 main 函數(shù)
        • 插件加載時(shí)會(huì)先執(zhí)行 init 函數(shù)

        Traefik Yaegi 實(shí)現(xiàn)

        Yaegi 是 Traefik 開源的 Go 解釋器。Traefik 自身的插件實(shí)現(xiàn)就是使用的 Yaegi 。

        Yaegi 運(yùn)行在 Go 運(yùn)行時(shí)之上,可以直接作為嵌入式解釋器,或使用交互式 shell ,解釋運(yùn)行 Go 代碼。不過只支持 Go 1.15 和 Go 1.16(最新的 2 個(gè)主要版本)。

        創(chuàng)建代碼目錄結(jié)構(gòu)如下:

        │  go.mod
        │  go.sum
        │  main.go

        └─plugin
            └─src
                └─hello
                        go.mod
                        hello.go

        這里有個(gè)注意點(diǎn),Yaegi 的插件需要放在 src 目錄下。

        其中 hello.go 代碼:

        package hello

        import (
         "fmt"
        )

        func init() {
         fmt.Println("hello plugin init")
        }

        func CallMe(msg string) string {
         fmt.Println(msg)
         return "I am plugin"
        }

        main.go 代碼:

        package main

        import (
         "fmt"
         "github.com/traefik/yaegi/interp"
         "github.com/traefik/yaegi/stdlib"
        )

        func main() {
         // 初始化解釋器
         i := interp.New(interp.Options{GoPath: "./plugin/"})

         // 插件需要使用標(biāo)準(zhǔn)庫
         if err := i.Use(stdlib.Symbols); err != nil {
          panic(err)
         }

         // 導(dǎo)入 hello 包
         if _, err := i.Eval(`import "hello"`); err != nil {
          panic(err)
         }

         // 調(diào)用 hello.CallMe
         v, err := i.Eval("hello.CallMe")
         if err != nil {
          panic(err)
         }
         callMe := v.Interface().(func(string) string)
         fmt.Println(callMe("togettoyou"))
        }
        go run main.go

        # 輸出
        hello plugin init
        togettoyou
        I am plugin



        推薦閱讀


        福利

        我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù) ebook 獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

        瀏覽 41
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久久久精品中文字幕 | chinese粉嫩露出vide | a一级视频| 漂亮的女社长被调教 | 色妞www精品视频7777 | 亚洲午夜激情视频 | 黄免费观看 | 国产精品视频1区2区3区 | 军人野外岔开腿呻吟bl | 天天操2017 |