追加到结果的切片中

huangapple go评论71阅读模式
英文:

Appending to a slice of results

问题

我正在尝试创建一个可以传递给模板以供用户显示的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}) //在这里抛出错误
    }
  }
  t, _ := template.ParseFiles("home.html")
  t.Execute(w, posts)
}

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

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

请问正确的做法是什么?

英文:

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?

答案1

得分: 3

你在内部作用域中有一个posts的短变量声明。因此,在内部作用域中的posts的短变量声明没有被使用。

posts := make([]Post, 0)
{
    posts := append(posts, Post{Title: title}) // 在这里抛出错误
}

你想要在内部作用域中对外部作用域中声明的变量posts进行赋值。

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

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

huangapple
  • 本文由 发表于 2013年4月28日 09:14:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/16258543.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定