Use a literal for type input
I am using the code in func Root
as a guide to create another method Login
shown below. Specifically, in Root
I assign to a literal Book{}
b
and then use the result in Scan
. This code does not throw any errors (although I'm not sure if this is good code), but when I try to do something like this in a function Login
that I am 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 don't I do the same in the second method, namely by assigning the variable a letter u := User{}
and then using it in the scan?
Can you explain using the code below when you can and cannot use a literal for a type in an assignment?
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
}
source to share
Simplifying your example to focus on the basics:
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() {}
A function declaration for Login
declares a result parameter u *User
, a pointer to a type User
.
An operator u := User{}
is a short type variable declaration User
.
Go Programming Language Specification
A short variable declaration uses the syntax:
ShortVarDecl = IdentifierList ": =" ExpressionList.
This is shorthand for declaring a regular variable with an expression initializer, but not types:
"var" IdentifierList = ExpressionList.
Unlike regular variable declarations, declaring a short variable can override variables if they were originally declared earlier in the same block with the same type and at least one of the non-empty variables is new. As a consequence, re-styling can only appear in a short declaration with multiple variables. The Redeclaration does not introduce a new variable; it just assigns a new value to the original.
Since the variable is u
already declared in the same ( u *User
) block , the compiler complains that it u := User{}
has " no new variables on left side of :=
". Write u = User{}
for a simple appointment.
A statement books := []Book{}
is a short variable declaration for a new variable book
in a block.
The declaration u *User
states that it u
is a pointer to a variable of the type User
.
Go Programming Language Specification
Composite literals build values for structures, arrays, slices, and maps, and create a new value each time they are evaluated. They consist of a value type followed by a parenthesized list of constituent elements. The element can be a single expression or a key-value pair.
LiteralType must be a structure, array, slice, or map type (the grammar enforces this restriction, unless the type is specified as TypeName). Expression types must be assigned to the appropriate field, element, and LiteralType key types; There is no additional conversion.
Taking the address of a compound literal creates a pointer to a unique instance of the literal value.
A compound literal User{}
is a literal type value User
, not a *User
. The compiler complains that " cannot use User literal (type User) as type *User in assignment
". Take the address of a compound literal for a pointer to a literal value of type User
( *User
). Write u = &User{}
.
source to share
-
b := Book{}
defines a new variable (b
not previously defined), so it can take on a value typeBook
-
u := User{}
doesn't define a new variable since it was part of the return parameter of the methodu *User
, so you can't use:=
.
It will beu=&User{}
.
u
here's the named result parameter :
if the function executes a return statement with no arguments, the current values of the result parameters are used as return values.
source to share