如何在 Go 中正确使用全局变量(以及更推荐的替代方案)

Go 中可通过包级变量实现跨函数访问数据,但更推荐通过函数参数传递值以保证代码可测试性和可维护性;本文详解两种方式的实现、差异及最佳实践。

Go 中可通过包级变量实现跨函数访问数据,但更推荐通过函数参数传递值以保证代码可测试性和可维护性;本文详解两种方式的实现、差异及最佳实践。

在 Go 语言中,“全局变量”实际指包级变量(package-scoped variables)——即声明在函数外部、位于包顶层的变量。它们在整个包内可见,所有函数均可读写(前提是变量名首字母大写且需导出时才对其他包可见)。但需注意:滥用包级变量会破坏函数的纯度、增加隐式依赖,降低可测试性与并发安全性。

✅ 方式一:使用包级变量(不推荐用于复杂逻辑)

修正原代码的关键在于:

package main

import (
    "fmt"
    "bufio"
    "os"
    "strconv"
)

var (
    inputX *bufio.Scanner
    inputY *bufio.Scanner
)

func main() {
    fmt.Print("LOADED!\n")
    fmt.Print("insert y value here: ")
    inputY = bufio.NewScanner(os.Stdin)
    inputY.Scan()

    inputXfunc()
}

func inputXfunc() {
    fmt.Print("insert x value here: ")
    inputX = bufio.NewScanner(os.Stdin)
    inputX.Scan()
    slope()
}

func slope() {
    yStr := inputY.Text()
    xStr := inputX.Text()

    y, err1 := strconv.ParseFloat(yStr, 64)
    x, err2 := strconv.ParseFloat(xStr, 64)
    if err1 != nil || err2 != nil {
        fmt.Println("Error: invalid number input")
        return
    }
    if x == 0 {
        fmt.Println("Error: division by zero")
        return
    }
    fmt.Printf("Slope (y/x) = %.2f\n", y/x)
}

⚠️ 注意事项

✅ 方式二:通过函数参数传递(强烈推荐)

更符合 Go 的工程实践:将输入值作为参数显式传入,使函数职责清晰、无隐藏依赖、天然可测试。

package main

import (
    "fmt"
    "bufio"
    "os"
    "strconv"
)

func main() {
    fmt.Print("LOADED!\n")

    fmt.Print("insert y value here: ")
    yStr := readInput()
    y, err := strconv.ParseFloat(yStr, 64)
    if err != nil {
        fmt.Println("Invalid y input")
        return
    }

    fmt.Print("insert x value here: ")
    xStr := readInput()
    x, err := strconv.ParseFloat(xStr, 64)
    if err != nil {
        fmt.Println("Invalid x input")
        return
    }

    slope(y, x)
}

// readInput 封装标准输入读取逻辑,复用性强
func readInput() string {
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan()
    return scanner.Text()
}

// slope 纯函数:仅依赖输入参数,无副作用,易于单元测试
func slope(y, x float64) {
    if x == 0 {
        fmt.Println("Error: division by zero")
        return
    }
    fmt.Printf("Slope (y/x) = %.2f\n", y/x)
}

优势总结

? 最终建议

遵循这一原则,你的 Go 代码将更健壮、可维护,也更贴近 Go 社区推崇的简洁务实风格。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。