在赋值中使用文字作为类型

时间:2014-08-15 19:13:03

标签: go

我使用func Root中的代码作为指南来创建下面显示的另一种方法Login。特别是,在Root中,我将文字Book{}分配给b,然后使用Scan中的结果。该代码不会抛出任何错误(虽然我不确定它是否是一个很好的代码),但是当我尝试在Login函数中执行类似的操作时,我会这样做; m从此blogpost修改,我收到此错误

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

为了它的价值,我在编译时也会出现这个错误

no new variables on left side of :=

但是我没有在第二种方法中做同样的事情,即将文字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
}

2 个答案:

答案 0 :(得分:6)

简化您的示例以专注于要点:

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

Login的函数声明声明了一个结果参数u *User,一个指向User类型的指针。

u := User{}语句是类型为User的简短变量声明。

  

The Go Programming Language Specification

     

Short variable declarations

     

短变量声明使用语法:

     

ShortVarDecl = IdentifierList":=" ExpressionList。

     

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

     

"无功" IdentifierList = ExpressionList。

     

与常规变量声明不同,短变量声明可以   重新声明变量,只要它们最初是在早些时候宣布的   具有相同类型的相同块,以及至少一个非空白块   变量是新的。因此,重新声明只能出现在   多变量简短声明。重新申报不会引入   新变量;它只是为原始版本赋予了一个新值。

由于变量u已在同一个块(u *User)中声明,因此编译器会抱怨u := User{}有" no new variables on left side of :=。&#34 ;写u = User{}进行简单的作业。

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

声明u *User表示u是指向User类型变量的指针。

  

The Go Programming Language Specification

     

Composite literals

     

复合文字构造结构,数组,切片和的值   映射并在每次评估时创建新值。他们包括   值的类型后跟一个大括号括号的复合列表   元素。元素可以是单个表达式或键值对。

     

LiteralType必须是结构,数组,切片或地图类型(   语法强制执行此约束,除非将类型指定为a   类型名)。表达式的类型必须可分配给   LiteralType的相应字段,元素和键类型;有   没有额外的转换。

     

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

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

答案 1 :(得分:2)

  • b := Book{}定义了一个新变量(b之前未定义过),因此可以采用值类型Book
  • u := User{}没有定义新变量,因为它是方法返回参数u *User的一部分,因此您无法使用:=
    它将是u=&User{}

u这是named result parameter

  

如果函数执行不带参数的return语句,则结果参数的当前值将用作返回值。