附加到一部分结果

I'm trying create a slice of sql results that can be passed to a template for display to the user. I have the following:

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)
}

On compile I'm given the error posts declared and not used. If I fmt.Println(posts) after the append call it compiles, but it seems to be reseting the value of posts on each iteration rather than appending.

What is the correct way to do this?

Declarations and scope

A declaration binds a non-blank identifier to a constant, type, variable, function, or package. Every identifier in a program must be declared. No identifier may be declared twice in the same block, and no identifier may be declared in both the file and package block.

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

The scope of a declared identifier is the extent of source text in which the identifier denotes the specified constant, type, variable, function, or package.

Go is lexically scoped using blocks:

  • The scope of a predeclared identifier is the universe block.
  • The scope of an identifier denoting a constant, type, variable, or function (but not method) declared at top level (outside any function) is the package block.
  • The scope of an imported package identifier is the file block of the file containing the import declaration.
  • The scope of an identifier denoting a function parameter or result variable is the function body.
  • The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.
  • The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block.

An identifier declared in a block may be redeclared in an inner block. While the identifier of the inner declaration is in scope, it denotes the entity declared by the inner declaration.

Short variable declarations

A short variable declaration uses the syntax:

ShortVarDecl = IdentifierList ":=" ExpressionList .

It is a shorthand for a regular variable declaration with initializer expressions but no types:

"var" IdentifierList = ExpressionList .

Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared in the same block with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.

You have a short variable declaration of posts in the inner scope. Therefore, the short variable declaration of posts in the inner scope is not used.

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

You want an assignment to posts, the variable declared in the outer scope, in the inner scope.

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