Как лениво инициализировать глобальные переменные пакета с помощью пользовательского ввода?

# #go #package

Вопрос:

В моих проектах есть несколько пакетов: основной и второстепенный. Основной принимает входные данные от пользователей и инициализирует некоторые переменные сам по себе. Вторичные пакеты содержат некоторые глобальные переменные, которые могут быть инициализированы только после того, как был инициализирован один из «основных» пакетов, и не ранее.

Я знаю о функции «init()» пакета, но в моем случае это не сработает, потому что она не способна инициализировать данные ленивым способом и с некоторыми аргументами или данными извне. В то время как это то, чего я хочу.

     //main package

    var (
        a1 int
        a2 float
        a3 string
        a4 MyStruct
        a5 MyStruct2
    )

    func main() {
        //process user input
        //...........
        //some other stuff


        // I want that by this point, the global variables of package2 to have been initialized
        // **based on** the processed user input from above
        //namely, before the first access to the package
        package2.Func1()

        // I want that by this point, the global variables of package3 to have been initialized
        // **based on** the processed user input from above
        //namely, before the first access to the package
        package3.Func11()

    }
 

Есть ли решение для этого?

У меня могла бы быть функция «initData()» в пакетах package2 и package3, но как я могу гарантировать, что ее не забудут вызвать как самую первую функцию в обязательном порядке перед вызовом любых других функций пакета?

Комментарии:

1. Если вы хотите назначить значения по требованию и убедиться, что они соответствуют назначенным, для этого вам необходимо включить меры предосторожности.

2. @JimB что такое гарантии?

3. существительное во множественном числе: меры предосторожности-мера, принятая […] для предотвращения чего-либо нежелательного , т. Е. проверьте, установлены ли значения, прежде чем что-либо делать, требуйте вызова функции инициализации, просто паникуйте, если что-то не так, и т. Д.

4. в main пакете init() тоже есть. это может быть хорошим местом для звонка initData .

5. Функционально это действительно не так. «Вторичные пакеты содержат некоторые глобальные переменные, которые могут быть инициализированы только после того, как был инициализирован один из «основных» пакетов, и не ранее». Чем больше я думаю об этом утверждении, тем больше оно кажется плохой организацией данных. Почему они являются глобальными и в этом пакете, если их ценности зависят от состояния их потребителя?

Ответ №1:

вероятно, вам следует использовать функцию инициализации в main.go

 
func init(){
    // get user input and set variables

    // call package 2 and 3 after setting the variables in main
    package2.Func1()
    package3.Func1()

}

func main(){
    // everything is setup properly when code in this main function is launched
}
 

Комментарии:

1. это не сработает, потому что я ожидаю ввода данных пользователем в main. Под пользовательским вводом я не имею в виду аргументы командной строки; Чем это вообще отличается от вызова этих 2 функций в main?

2. тогда я не понимаю вашей проблемы, просто введите данные пользователя в main, а затем установите переменные в других пакетах, вы используете init для установки параметров перед вызовом main, что похоже на то, что вы хотите, потому что вы хотите инициализировать переменные перед запуском main

3. ДА. Но я предпочел бы сделать это более правильным способом. В противном случае, что, если кто-то решит вызвать любую функцию из package2 до того, как в ней будут инициализированы переменные?

4. скажите своим пользователям, чтобы они инициализировали вещи перед их использованием, это все, что вы можете сделать,

5. плохой совет…….