2015-10-24 3 views
0

У меня есть структуры в файл, который начинается с этой строки:Как импортировать определенную платформой структуру?

// +build windows 

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

Например, если файл содержит функцию newWindowsSpecificThing() и компилируется в Linux, функция не будет существовать, потому что она определена в файле, который не компилируется. (И, конечно, это приведет к ошибке.)

Как мне обойти эту дилемму?

+0

Поместите 'newWindowsSpecifcThing()' в 'init' в файл' foo_windows.go'. –

ответ

3

Где-то у вас есть функция, которая вызывает newWindowsSpecificThing(). Это должно быть в файле, специфичном для Windows. Если бы это было так, то не имело бы значения, что оно недоступно. Тот факт, что у вас есть что-то «проверьте, работает ли он в Windows», предлагает где-то оператор if runtime.GOOS == "windows". Вместо этого переместите весь if в функцию, определенную в файле Windows. Вам также нужно будет определить эту функцию в файле !windows, что отлично.

В качестве примера из моего кода, у меня есть функция:

func Setup() *config { 
    var cfg *config 
    // setup portable parts of cfg 
    return PlatformSpecificSetup(cfg) 
} 

Я тогда файл, помеченный // +build windows, который определяет PlatformSpecificSetup() в одну сторону, а другой отмечен // +build !windows, что определяет его другой. Мне никогда не нужно проверять runtime.GOOS, и мне никогда не придется иметь дело с неопределенными типами данных. Сама структура config определена в этих файлах, поэтому она может иметь разные поля для каждой платформы (если они достаточно согласны для Setup()). Если бы я был быть более осторожным, я мог бы создать на структуру типа:

type config struct { 
    // independent stuff 
    plat *platformConfig 
} 

А потом просто определить platformConfig в каждом файле платформы, но на практике я обнаружил, что больше проблем, чем это стоит.

4

Я думаю, что ваше решение будет иметь некоторый метод для вашей структуры, который используется на всех платформах. Посмотрите, как файлы dir_*.go работают для пакета os. func (file *File) readdirnames(n int) (names []string, err error) доступен на всех платформах, предоставляя его в dir_plan9.go, dir_unix.go и dir_windows.go.

Для вашей проблемы, я бы взял тот же подход, но с каким-то общим методом, который делает внутренний работы. В вашей логике приложения вы бы вызвали эту функцию, и в вашем файле file_unix.go вы бы определили эту функцию, чтобы ничего не делать (пустой корпус).