1

我正在尝试创建一段 sql 结果,可以将其传递给模板以显示给用户。我有以下内容:

type Post struct {
  Title string
}

func landing(w http.ResponseWriter, r *http.Request){
  posts := make([]Post, 0)
  conn := OpenConnection()
  defer conn.Close()
  rows, err := conn.Query("SELECT p.title FROM posts p LIMIT 100")
  if err != nil {
    fmt.Println(err)
  } else {
    for rows.Next() {
      var title string
      rows.Scan(&title)
      posts := append(posts, Post{Title: title}) //error thrown here
    }
  }
  t, _ := template.ParseFiles("home.html")
  t.Execute(w, posts)
}

func main() {
  http.HandleFunc("/", landing)
}

在编译时,我得到了错误posts declared and not used。如果我fmt.Println(posts)在追加调用之后编译它,但它似乎是在每次迭代中重置帖子的值而不是追加。

这样做的正确方法是什么?

4

1 回答 1

3

声明和范围

声明将非空白标识符绑定到常量、类型、变量、函数或包。必须声明程序中的每个标识符。一个标识符不能在同一个块中声明两次,也不能在文件块和包块中都声明标识符。

Declaration   = ConstDecl | TypeDecl | VarDecl .
TopLevelDecl  = Declaration | FunctionDecl | MethodDecl .

声明标识符的范围是源文本的范围,其中标识符表示指定的常量、类型、变量、函数或包。

Go 的词法范围使用块:

  • 预声明标识符的范围是 Universe 块。
  • 表示在顶层(任何函数之外)声明的常量、类型、变量或函数(但不是方法)的标识符的范围是包块。
  • 导入包标识符的范围是包含导入声明的文件的文件块。
  • 表示函数参数或结果变量的标识符的范围是函数体。
  • 在函数内声明的常量或变量标识符的范围从 ConstSpec 或 VarSpec(短变量声明的 ShortVarDecl)的末尾开始,并在最里面的包含块的末尾结束。
  • 在函数内声明的类型标识符的范围从 TypeSpec 中的标识符开始,到最里面的包含块的末尾结束。

在块中声明的标识符可以在内部块中重新声明。虽然内部声明的标识符在范围内,但它表示由内部声明声明的实体。

简短的变量声明

简短的变量声明使用以下语法:

ShortVarDecl = IdentifierList ":=" ExpressionList .

它是带有初始化表达式但没有类型的常规变量声明的简写:

"var" IdentifierList = ExpressionList .

与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初是在同一块中以相同类型声明的,并且至少有一个非空白变量是新的。因此,重新声明只能出现在多变量短声明中。重新声明不引入新变量;它只是为原始值分配一个新值。

posts您在内部范围中有一个简短的变量声明。posts因此,不使用内部范围内的短变量声明。

posts := make([]Post, 0)
{
    posts := append(posts, Post{Title: title}) //error thrown here
}

您希望posts在内部范围内对在外部范围内声明的变量进行赋值。

posts := make([]Post, 0)
{
    posts = append(posts, Post{Title: title})
}
于 2013-04-28T01:42:57.287 回答