Golang中如何根据不同操作系统设置变量
Golang中如何根据不同操作系统设置变量 有什么关于如何为每个GOOS设置一组变量的提示吗? switch语句无法定义变量,无论是在main()函数中还是在init()块中。
switch os := runtime.GOOS; os {
case "windows", "arm64":
var (
foo = "bar1"
// ... set more vars ...
)
case "arm":
var (
foo = "bar2"
// ... set more vars ...
)
default:
var (
foo = "bar3"
// ... set more vars ...
)
}
fmt.Printf("%#v \n", foo) // 失败:"undefined: foo"
更多关于Golang中如何根据不同操作系统设置变量的实战教程也可以访问 https://www.itying.com/category-94-b0.html
作用域!明白了。所以,使用独立的变量声明,而不是在 switch/default 分支中声明,然后在 switch 中根据条件重置变量值,而不是重新声明。谢谢。
更多关于Golang中如何根据不同操作系统设置变量的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
嗯,如果将来要使用多个变量,使用 switch 语句并不那么符合惯用法,而且会变得复杂。更好的方法是使用条件编译,并为每个架构或操作系统创建单独的文件。可以参考 Dave Cheney 的文章了解如何实现这一点。
https://dave.cheney.net/2013/10/12/how-to-use-conditional-compilation-with-the-go-build-tool
试试这个:
package main
import (
"fmt"
"runtime"
)
func main() {
var opsys string
switch runtime.GOOS {
case "windows", "arm64":
opsys = "Microsoft Windows or ARM64"
case "arm":
opsys = "ARM"
case "linux":
opsys = "Linux"
default:
opsys = "other"
}
fmt.Printf("Host system: %#v \n", opsys)
}
在 Go Playground 上查看:Go Playground - The Go Programming Language
Go 是一门块作用域语言。
通过在 switch 语句内部声明 foo 变量,你只能在该代码块内部使用该 foo 变量。当执行离开该代码块时,如果存在另一个名为 foo 的变量,那么你的 fmt.Printf() 语句访问的将是那个变量。
这是一个更简单的示例:
package main
import "fmt"
func main() {
var1 := 2
{
var1 := 3
fmt.Printf("Inside the block, var1 = %d\n",var1)
}
fmt.Printf("Outside the block, var1 = %d\n",var1)
}
该程序输出:
在代码块内部,var1 = 3
在代码块外部,var1 = 2
在 Go Playground 上查看:Go Playground - The Go Programming Language
如果你不理解这一点,请移除第 6 行和第 9 行的 { } 大括号,然后再次运行代码。首先,你会收到关于重新声明 var1 的错误,因此将 var1 := 3 改为 var1 = 3。
然后再次运行,查看输出结果:
在代码块内部,var1 = 3
在代码块外部,var1 = 3
在 Go Playground 上查看:Go Playground - The Go Programming Language
在Go语言中,switch语句的每个case分支都会创建一个独立的词法作用域,这就是为什么在switch外部无法访问case内部定义的变量。以下是几种正确的解决方案:
方案1:在switch外部声明变量,在case中赋值
package main
import (
"fmt"
"runtime"
)
func main() {
var foo string
switch os := runtime.GOOS; os {
case "windows", "arm64":
foo = "bar1"
case "arm":
foo = "bar2"
default:
foo = "bar3"
}
fmt.Printf("%#v \n", foo)
}
方案2:使用函数返回值
package main
import (
"fmt"
"runtime"
)
func getOSConfig() (foo string, bar int) {
switch os := runtime.GOOS; os {
case "windows", "arm64":
foo = "bar1"
bar = 100
case "arm":
foo = "bar2"
bar = 200
default:
foo = "bar3"
bar = 300
}
return
}
func main() {
foo, bar := getOSConfig()
fmt.Printf("foo: %#v, bar: %d\n", foo, bar)
}
方案3:使用结构体配置
package main
import (
"fmt"
"runtime"
)
type Config struct {
Foo string
Bar int
Baz bool
}
func getConfig() Config {
switch os := runtime.GOOS; os {
case "windows", "arm64":
return Config{
Foo: "bar1",
Bar: 100,
Baz: true,
}
case "arm":
return Config{
Foo: "bar2",
Bar: 200,
Baz: false,
}
default:
return Config{
Foo: "bar3",
Bar: 300,
Baz: true,
}
}
}
func main() {
config := getConfig()
fmt.Printf("Config: %+v\n", config)
}
方案4:使用包级变量和init函数
package main
import (
"fmt"
"runtime"
)
var (
foo string
bar int
)
func init() {
switch os := runtime.GOOS; os {
case "windows", "arm64":
foo = "bar1"
bar = 100
case "arm":
foo = "bar2"
bar = 200
default:
foo = "bar3"
bar = 300
}
}
func main() {
fmt.Printf("foo: %#v, bar: %d\n", foo, bar)
}
方案5:使用map配置
package main
import (
"fmt"
"runtime"
)
var osConfig = map[string]struct {
foo string
bar int
}{
"windows": {"bar1", 100},
"arm64": {"bar1", 100},
"arm": {"bar2", 200},
"default": {"bar3", 300},
}
func main() {
config, exists := osConfig[runtime.GOOS]
if !exists {
config = osConfig["default"]
}
fmt.Printf("foo: %#v, bar: %d\n", config.foo, config.bar)
}
推荐使用方案1或方案3,它们在代码可读性和维护性方面表现最好。方案1适合简单的变量赋值,方案3适合需要配置多个相关变量的场景。

