dongqing344716 2014-08-15 11:13
浏览 29
已采纳

使用文字来进行赋值

I'm using the code in func Root as a guide to create another method Login shown below. In particular, in Root, I assign the literal Book{} to b and then use the result in the Scan. That code doesn't throw any errors (although I'm not sure if it's nice code), but when I try to do something similar in the Login function, which I'm modifying from this blogpost, I get this error

cannot use User literal (type User) as type *User in assignment

for what it's worth, I also get this error right above when I compile

no new variables on left side of :=

but aren't I doing the same thing in the second method, namely assigning the literal u := User{} to a variable and then using it in the scan?

Can you explain using the code below when you can and can't use a literal for type in an assignment?

  1. func Root(w http.ResponseWriter, r *http.Request) {
  2. rows, err := db.Query("SELECT title, author, description FROM books")
  3. books := []Book{}
  4. for rows.Next() {
  5. b := Book{}
  6. err := rows.Scan(&b.Title, &b.Author, &b.Description)
  7. PanicIf(err)
  8. books = append(books, b)
  9. }
  10. ...//code ommitted
  11. func Login(password, email string) (u *User, err error) {
  12. u := User{}
  13. db.QueryRow("select * from users where email=$1 ", email).Scan(&u.Id, &u.Password, &u.Email)
  14. if err != nil {
  15. return
  16. }
  17. err = bcrypt.CompareHashAndPassword(u.Password, []byte(password))
  18. if err != nil {
  19. u = nil
  20. }
  21. return
  22. }

展开全部

  • 写回答

2条回答 默认 最新

  • dongxin1999 2014-08-15 13:15
    关注

    Simplifying your example to focus on the essentials:

    package main
    
    import "net/http"
    
    type Book struct{}
    
    type User struct{}
    
    func Root(w http.ResponseWriter, r *http.Request) {
        books := []Book{}
        _ = books
    }
    
    func Login(password, email string) (u *User, err error) {
        // no new variables on left side of :=
        // cannot use User literal (type User) as type *User in assignment
        // u := User{}
        u = &User{}
        return
    }
    
    func main() {}
    

    The function declaration for Login declares a result parameter u *User, a pointer to type User.

    The u := User{} statement is a short variable declaration of type User.

    The Go Programming Language Specification

    Short variable declarations

    A short variable declaration uses the syntax:

    ShortVarDecl = IdentifierList ":=" ExpressionList .

    It is 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 earlier 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.

    Since the variable u has already been declared in the same block (u *User), the compiler complains that u := User{} has "no new variables on left side of :=." Write u = User{} for a simple assignment.

    The statement books := []Book{} is a short variable declaration for a new variable, book, in the block.

    The declaration u *User says that u is a pointer to a variable of type User.

    The Go Programming Language Specification

    Composite literals

    Composite literals construct values for structs, arrays, slices, and maps and create a new value each time they are evaluated. They consist of the type of the value followed by a brace-bound list of composite elements. An element may be a single expression or a key-value pair.

    The LiteralType must be a struct, array, slice, or map type (the grammar enforces this constraint except when the type is given as a TypeName). The types of the expressions must be assignable to the respective field, element, and key types of the LiteralType; there is no additional conversion.

    Taking the address of a composite literal generates a pointer to a unique instance of the literal's value.

    The composite literal User{} is a literal value of type User, not *User. The compiler complains that "cannot use User literal (type User) as type *User in assignment." Take the address of the composite literal for a pointer to a literal value of type User (*User). Write u = &User{}.

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部