глобальные переменные в рамках плагина и пакета - PullRequest
1 голос
/ 08 ноября 2019

У меня есть пакет Go для управления конфигурацией. В пакете есть неэкспортированная переменная, инициализированная в функции init, которая содержит данные конфигурации. Пользователь взаимодействует с конфигурацией через экспортированные функции, которые внутренне обращаются к глобальной переменной. Примерно так:

pakage config

var gConfig ...

func init() {
    gConfig = ...
}

func Value(name string) (string, error) {
    return gConfig.value(name)
}

Я подумываю об использовании плагинов и исследую влияние на мой пакет конфигурации.

Если плагин импортирует пакет конфигурации и вызывает некоторые из его экспортируемых функций, какая переменная gConfig будет использоваться? Будет ли у плагина собственный внутренний экземпляр config с собственной переменной gConfig, инициализированной при загрузке плагина, или же плагин будет динамически связываться во время загрузки для использования основной переменной gConfig программы, инициализированной при запуске программы?

1 Ответ

1 голос
/ 08 ноября 2019

согласно документации

Пакетный плагин реализует загрузку и разрешение символов плагинов Go. Когда плагин открывается впервые, функции инициализации всех пакетов, которые еще не являются частью программы, называются . Основная функция не запускается. Плагин инициализируется только один раз и не может быть закрыт .

Кроме того, вы не можете импортировать один и тот же плагин дважды.

Будет ли плагин иметьего собственный внутренний экземпляр config с собственной переменной gConfig, инициализированной при загрузке плагина

, плагин будет иметь свою собственную переменную в своей области видимости.

Если плагин импортируетпакет config и вызывает некоторые из его экспортируемых функций, какая переменная gConfig будет использоваться?

переменная, определенная в пакете, как вы продемонстрировали.

Чтобы проверить это, напишитенебольшая демонстрация. Go очень прост и эффективен, выполнение этого занимает очень мало времени, см.

    $ tree .
    .
    ├── main.go
    ├── plug
    │   └── plugin.go
    └── plugin.so

    1 directory, 3 files
// $ cat plug/plugin.go 
package main

var pkgGlobal = map[string]string{}

func Set(k, v string) {
    pkgGlobal[k] = v
}
func Get(k string) string {
    return pkgGlobal[k]
}
// $ cat main.go 
package main

import (
    "fmt"
    "plugin"
)

func main() {
    p, err := plugin.Open("plugin.so")
    if err != nil {
        panic(err)
    }
    var get func(string) string
    {
        x, err := p.Lookup("Get")
        if err != nil {
            panic(err)
        }
        get = x.(func(string) string)
    }
    var set func(string, string)
    {
        x, err := p.Lookup("Set")
        if err != nil {
            panic(err)
        }
        set = x.(func(string, string))
    }

    set("tomate", "rouge")
    fmt.Println(get("tomate"))
    fmt.Println(get("notomate"))
}

сборка и запуск

$ go build -buildmode=plugin -o plugin.so plug/plugin.go 
$ go run main.go 
rouge

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...