我正在使用代码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)
简化示例以关注要点:
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。
简短的变量声明使用以下语法:
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。
复合文字量为结构,数组,切片和映射构造值,并在每次对其求值时创建一个新值。它们由值的类型和紧随其后的复合元素列表组成。元素可以是单个表达式或键值对。
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{}。
| 归档时间: |
|
| 查看次数: |
17447 次 |
| 最近记录: |