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