在作业中使用文字作为类型

Lea*_*cim 6 go

我正在使用代码func Root作为指南来创建Login下面显示的另一种方法.特别是,在Root我指定的文字Book{}b,然后使用该结果的Scan.该代码不会抛出任何错误(虽然我不确定它是不是很好的代码),但是当我尝试在Login函数中执行类似的操作时,我正在修改此博客帖子,我收到此错误

cannot use User literal (type User) as type *User in assignment
Run Code Online (Sandbox Code Playgroud)

对于它的价值,当我编译时,我也会在上面得到这个错误

no new variables on left side of :=
Run Code Online (Sandbox Code Playgroud)

但是我不是在第二种方法中做同样的事情,即将文字分配给u := User{}变量然后在扫描中使用它?

你可以解释使用下面的代码,并且不能在作业中使用文字作为类型吗?

func Root(w http.ResponseWriter, r *http.Request) {

    rows, err := db.Query("SELECT title, author, description FROM books")
    books := []Book{}
    for rows.Next() {
        b := Book{}
        err := rows.Scan(&b.Title, &b.Author, &b.Description)
        PanicIf(err)
        books = append(books, b)
    }
    ...//code ommitted



func Login(password, email string) (u *User, err error) {
    u := User{}
    db.QueryRow("select * from users where email=$1 ", email).Scan(&u.Id, &u.Password, &u.Email)
    if err != nil {
        return
    }

    err = bcrypt.CompareHashAndPassword(u.Password, []byte(password))
    if err != nil {
        u = nil
    }
    return
}
Run Code Online (Sandbox Code Playgroud)

pet*_*rSO 7

简化示例以关注要点:

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() {}
Run Code Online (Sandbox Code Playgroud)

函数声明用于Login声明结果参数u *User,即类型的指针User

u := User{}语句是type的简短变量声明User

Go编程语言规范

简短的变量声明

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

ShortVarDecl = IdentifierList“:=” ExpressionList。

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

“ var” IdentifierList = ExpressionList。

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

由于该变量u已在同一块(u *User)中声明,因此编译器会抱怨它u := User{}带有“” no new variables on left side of :=。写u = User{}一个简单的作业。

该语句books := []Book{}book该块中新变量的简短变量声明。

该声明u *User说这u是指向type变量的指针User

Go编程语言规范

复合文字

复合文字量为结构,数组,切片和映射构造值,并在每次对其求值时创建一个新值。它们由值的类型和紧随其后的复合元素列表组成。元素可以是单个表达式或键值对。

LiteralType必须是struct,array,slice或map类型(语法强制执行此约束,除非将类型指定为TypeName)。表达式的类型必须可分配给LiteralType的相应字段,元素和键类型;没有其他转换。

获取复合文字的地址会生成一个指向文字值的唯一实例的指针。

复合文字User{}是类型的文字值User,不是*User。编译器抱怨“ cannot use User literal (type User) as type *User in assignment。” 取复合文字的地址作为指向类型User*User)的文字值的指针。写u = &User{}