Правильный способ выбора func во время выполнения для разных операционных систем
Мне действительно нравится легкость кросс-компиляции/платформы для многих задач, которые я могу получить с помощью GO. У меня есть вопрос относительно, я думаю, эквивалента конструкции типа #ifdef/#else для выполнения/компиляции функции, основанной на операционной системе.
Вот сценарий - скажем, у меня есть функция, которая вставляет информацию в структуры управления ОС для запуска процесса при следующем запуске системы пользователем. В Windows я бы обновил запись реестра "RUN/RUNONCE" для пользователя, в MAC была бы запись plist и т.д.
По сути, я хотел бы иметь возможность написать кого-то, аналогичного этому (или перегрузить определенные функции ОС):
func setStartupProcessLaunch () {
if [OS is Windows] {
updateRegistry(){}
} else if [OS is Darwin] {
updatePlist(){}
} else if [OS is Linux] {
doLinuxthing() {}
}
}
При статической компиляции любая из не вызванных подпрограмм будет помечена как ошибка компиляции. Поэтому в идеале я хотел бы заключить мои функции doSpecificOS() в блоки #ifdef WINDOWS, #ifdef MAC-типа - как правильно это сделать? Я надеюсь, что мне не нужно создавать несколько деревьев проектов одной и той же программы для каждой платформы ОС.
Ответы
Ответ 1
Вы можете создавать файлы со следующим шаблоном: <pkgname>_<osname>.go
Например:
- your_package_linux.go
- your_package_darwin.go
- your_package_windows.go
Каждый файл может содержать определение функции для конкретных os, в вашем случае это func setStartupProcessLaunch()
.
Вы можете увидеть, как он реализован в стандартном os/signal пакете .
Ответ 2
Здесь вы можете прочитать Конструктивные ограничения http://golang.org/pkg/go/build/ (вы можете сделать три файла, каждый файл имеет логика для конкретной ОС)
Или, может быть, вы можете проверить runtime.GOOS для строки имени операционной системы
Ответ 3
Вы можете поместить свои функции в массив или карту, если все они принимают одинаковые числа/типы аргументов и имеют одинаковый тип возврата.
Вот пример, иллюстрирующий:
package main
import (
"fmt"
)
var functionMap = map[string]func(int)int{}
var functionArray = [2]func(int)int{nil, nil}
func windowsFunc(x int) int {
fmt.Printf("Hi from windowsFunc(%d)\n", x)
return 0
}
func linuxFunc(x int) int {
fmt.Printf("Hi from linuxFunc(%d)\n", x)
return 1
}
func main() {
functionMap["Windows"] = windowsFunc
functionMap["Linux"] = linuxFunc
functionArray[0] = windowsFunc
functionArray[1] = linuxFunc
fmt.Printf("Calling functionMap[\"Windows\"]: ")
functionMap["Windows"](123)
fmt.Printf("Calling functionArray[1]: ")
functionArray[1](456)
}
И результат:
Вызов функцииMap [ "Windows" ]: Привет от windowsFunc (123)
Вызов функцииArray [1]: Привет от linuxFunc (456)