在不同的操作系统上运行时选择func的正确方法

I really like the cross-compile/platform ease for many tasks that I can get with GO. I have a question regarding, I guess, the equivalent of a #ifdef / #else type of construct for executing/compiling a function based upon the operating system.

Here's the scenario - let's say I have a function that inserts information into the OS's control structures to launch a process at the next time the user starts up their system. On Windows I would update the 'RUN/RUNONCE' registry entry for the user, on MAC there would be a plist entry, etc.

In essence, I'd like to be able to write someone analogous to this (or have overloaded OS specific functions):

func setStartupProcessLaunch () {
    if [OS is Windows] {
        updateRegistry(){}
    } else if [OS is Darwin] {
        updatePlist(){}
    } else if [OS is Linux] {
        doLinuxthing() {}
    }
}

Given the static compilation, any of the routines that aren't called would be flagged as a compilation error. So ideally, I'd like to surround my 'doSpecificOS()' functions in #ifdef WINDOWS, #ifdef MAC type of blocks -- what's the proper way to accomplish this? My hope is that I don't need to create several project trees of the same program for each OS platform.

You could put your functions in an array or map if they all the take the same number/kinds of arguments and have the same return type.

Here's an example to illustrate:

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)
", x)
    return 0 
}

func linuxFunc(x int) int {
    fmt.Printf("Hi from linuxFunc(%d)
", 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)
}

And the output is:

Calling functionMap["Windows"]: Hi from windowsFunc(123)
Calling functionArray[1]: Hi from linuxFunc(456)

You can read about Build Constraints here http://golang.org/pkg/go/build/ (you can make three files, each file has the logic for a specific OS)
Or maybe you can check the runtime.GOOS for the OS name string

You could create files with following pattern: <pkgname>_<osname>.go

For example:

  • your_package_linux.go
  • your_package_darwin.go
  • your_package_windows.go

Each file could contain function definition for concrete os, in your case it is func setStartupProcessLaunch().

You could see how it is implemented in standard os/signal package for example.