【问题标题】:Global variables not persisting from CLI command全局变量不从 CLI 命令持久化
【发布时间】:2018-06-27 11:10:31
【问题描述】:
package main

import (
    "fmt"
    "net/http"
    "os"
    "strconv"

    "github.com/go-chi/chi"
)

var tests []string

func main() {

    if len(os.Args[:]) > 1 {
        tests = append(tests, "test")
        fmt.Println(strconv.Itoa(len(tests)) + " tests")
        os.Exit(0)
    }

    r := chi.NewRouter()
    r.Get("/", func(w http.ResponseWriter, r *http.Request) {
        tests = append(tests, "test")
        fmt.Println(strconv.Itoa(len(tests)) + " tests")
    })

    http.ListenAndServe(":8086", r)
}

当我从 localhost:8086 访问程序时,它工作正常,我可以看到 len(tests) 在刷新时增加。

但是当我使用./test arg 命令访问程序时,len(tests) 会递增到 1,但随后会丢失,所以下次它会说 1,并且永远不会再高了。

我认为这两种方法也应该共享相同的tests 值,但是当我写入一个时,另一个无法读取它等等。

谢谢。

【问题讨论】:

  • 你是说你不明白为什么你的程序不会在程序重新运行之间保留全局变量吗?
  • @mkopriva 是的,我一直认为程序运行时,我用来访问它的任何方法都会看到相同的全局变量。
  • 执行带有 arg 或没有 arg 的程序总是会启动一个带有空测试片的新进程,并且不知道可能已经在运行的其他 ./test 程序。如果给出 arg,它将退出,如果没有给出 arg,它将在 8086 上侦听。如果你想要一个 cli 与服务器通信,你需要两个程序和一个关于它们如何共享数据的策略。一个带有全局变量的程序不是让它工作的方法。

标签: go command-line-interface


【解决方案1】:

tests 是一个全局变量。只要您的进程在运行,它就会保持其值。

但是,当您运行./test arg 时,这会启动一个新进程,将一个元素添加到tests,然后退出。下一次调用./test arg 是一个全新的进程,它无法与上一次调用共享信息。

./test arg 运行的进程也与当前运行的以./test 启动的Web 服务器完全不同。同样的事情:它们不共享任何状态,它们只是碰巧是同一个二进制文件。

如果您想在给定程序的调用之间保留某些内容,则需要将数据保存在某处(文件、数据库等)。

【讨论】:

  • 谢谢,很有帮助。在我的真实项目中,它是一组 websocket 连接,所以不确定我是否可以将它们存储到文件中,我想我必须通过 http 而不是 cli 触发。
猜你喜欢
  • 2015-06-22
  • 2016-09-27
  • 2021-01-02
  • 2015-04-15
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多