【问题标题】:Non-declaration statement outside function body in GoGo中函数体之外的非声明语句
【发布时间】:2013-12-28 18:57:03
【问题描述】:

我正在为提供 JSON 或 XML 格式数据的 API 构建 Go 库。

此 API 要求我每 15 分钟左右请求一次session_id,并在调用中使用它。例如:

foo.com/api/[my-application-id]/getuserprofilejson/[username]/[session-id]
foo.com/api/[my-application-id]/getuserprofilexml/[username]/[session-id]

在我的 Go 库中,我试图在 main() 函数之外创建一个变量,并打算 ping 它以获取每个 API 调用的值。如果该值为 nil 或为空,则请求新的会话 id 等等。

package apitest

import (
    "fmt"
)

test := "This is a test."

func main() {
    fmt.Println(test)
    test = "Another value"
    fmt.Println(test)

}

什么是惯用的 Go 方式来声明一个全局可访问的变量,但不一定是一个常量?

我的test 变量需要:

  • 可以从它自己的包中的任何地方访问。
  • 多变

【问题讨论】:

    标签: variables scope go package global


    【解决方案1】:

    当我尝试运行具有如下函数定义的 Go 应用程序时遇到此错误:

    (u *UserService) func GetAllUsers() (string, error) {...} //Error code
    

    定义函数(接收函数)的正确方法是:

    func (u *UserService) GetAllUsers() (string, error) {...} //Working code
    

    【讨论】:

      【解决方案2】:

      短变量声明,即:=,只能在函数中使用。

      例如

      func main() {
          test := "this is a test"
          // or
          age := 35
      }
      

      函数之外的声明,你必须使用 var, func, const 等关键字,这取决于你想要什么(在这种情况下,我们使用 var

      在函数外部声明变量使其在其包中可访问。

      package apitest
      
      import (
          "fmt"
      )
      // note the value can be changed
      var test string = "this is a test"
      
      func main() {
          fmt.Println(test)
          test = "Another value"
          fmt.Println(test)
      
      }
      

      额外信息

      如果您希望变量在其包内外均可访问,则该变量必须大写,例如

      var Test string = "this is a test"
      

      这将使它可以从任何包中访问。

      【讨论】:

        【解决方案3】:

        在函数之外,每个语句都以关键字(varfunc 等)开头,因此 := 构造不可用。

        您可以在此处阅读更多信息:https://tour.golang.org/basics/10

        【讨论】:

          【解决方案4】:

          你需要

          var test = "This is a test"
          

          := 仅在函数中有效,小写的 't' 仅对包可见(未导出)。

          更详尽的解释

          test1.go

          package main
          
          import "fmt"
          
          // the variable takes the type of the initializer
          var test = "testing"
          
          // you could do: 
          // var test string = "testing"
          // but that is not idiomatic GO
          
          // Both types of instantiation shown above are supported in
          // and outside of functions and function receivers
          
          func main() {
              // Inside a function you can declare the type and then assign the value
              var newVal string
              newVal = "Something Else"
          
              // just infer the type
              str := "Type can be inferred"
          
              // To change the value of package level variables
              fmt.Println(test)
              changeTest(newVal)
              fmt.Println(test)
              changeTest(str)
              fmt.Println(test)
          }
          

          test2.go

          package main
          
          func changeTest(newTest string) {
              test = newTest
          }
          

          输出

          testing
          Something Else
          Type can be inferred
          

          另外,对于更复杂的包初始化或设置包所需的任何状态,GO 提供了一个 init 函数。

          package main
          
          import (
              "fmt"
          )
          
          var test map[string]int
          
          func init() {
              test = make(map[string]int)
              test["foo"] = 0
              test["bar"] = 1
          }
          
          func main() {
              fmt.Println(test) // prints map[foo:0 bar:1]
          }
          

          Init 将在 main 运行之前被调用。

          【讨论】:

          • 如果存在初始化器,类型可以省略;该变量将采用初始化程序的类型。
          【解决方案5】:

          我们可以如下声明变量:

          package main
          
          import (
                 "fmt"
                 "time"
          )
          
          var test = "testing"
          var currtime = "15:04:05"
          var date = "02/01/2006"
          
          func main() {
              t := time.Now()
              date := t.Format("02/01/2006")
              currtime := t.Format("15:04:05")
          
              fmt.Println(test) //Output: testing
              fmt.Println(currtime)//Output: 16:44:53
              fmt.Println(date) // Output: 29/08/2018
          }
          

          【讨论】:

            【解决方案6】:

            如果您不小心使用了“Func”或“function”或“Function”而不是“func " 你还会得到:

            函数体之外的非声明语句

            发布这个是因为我最初在这里搜索以找出问题所在。

            【讨论】:

            • 或者如果你拼写了func,省略关键字和函数名之间的空格
            • 我写了void main() 并登陆了这里,是吗?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-02
            • 2012-04-21
            • 1970-01-01
            • 2020-06-08
            相关资源
            最近更新 更多