This question already has answers here:
What is "_," (underscore comma) in a Go declaration?
(9 answers)
Closed 7 years ago.
I'm new to Go and came across this line of code while browsing through some other threads:
if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err)
What does the _, after the if mean? Is it specifying that something will be assigned in the if condition (as it appears is happening with err)? I couldn't find an example of this syntax on the wiki and I'm very curious to see what it's used for.
Here's a link to the thread I was looking at if it helps:
How to check if a file exists in Go?
Because os.Stat returns two values, you have to have somewhere to receive those if you want any of them. The _ is a placeholder that essentially means "I don't care about this particular return value." Here, we only care to check the error, but don't need to do anything with the actual FileInfo Stat gives us.
The compiler will just throw that value away.
Related
This question already has an answer here:
Statement blocks in go
(1 answer)
Closed 7 months ago.
when writing gin(a go web frame) code, I found a
piece of code like this:
r := gin.New()
apiv1 := r.Group("/api/v1")
{ // don't understand
apiv1.GET("/tags", v1.GetTags)
apiv1.POST("/tags", v1.AddTag)
}
It's ok and have no warn or error.
But I do don't know what's the newline braces mean, or it just has no effect?
From Go spec docs
blocks nest and influence scoping
This question already has answers here:
Go: Unused variable
(2 answers)
Closed 1 year ago.
I have code that loops through each rune of a string like so:
for i, character := range "abcdefghjklmnopqrstuv" {
fmt.Printf("character and i: ", character, i)
}
However, I have no need do anything with i. I only need that for the loop to work. If I leave i out of fmt.Printf, the compiler complains that I have defined something I did not use. If I leave i in, it clutters my console output.
How can I can tell the compiler to ignore the unused variable?
Use the blank identifier _:
for _, character := range "abcdefghjklmnopqrstuv" {
fmt.Printf("character: ", character)
}
This is covered in the Tour of Go.
I understand the confusion.
Unlike most program languages Go does not allow unused variables. This is because of a design decision to enforce that on this level unlike as a optional choice for each developer as other languages do.
So you can use the blank identifier as another answer mentioned but this is because of the way Go works.
This question already has answers here:
Typecasting in Golang
(5 answers)
Closed 2 years ago.
Reading this https://github.com/go-pg/pg/wiki/Writing-Queries#select I see many times this expression:
(*Book)(nil)
Example:
count, err := db.Model((*Book)(nil)).Count()
What does it mean?
That is a type conversion. Assuming the db.Model function takes interface{}, it sends an nil interface of type *Book to the function.
To convert a value v to type Book, you'd write:
Book(v)
However, you cannot write Book(nil) because nil is a pointer and Book is not. If you had a type
type BookPtr *Book
Then you could've written BookPtr(nil). Extending that, you want to write *Book(nil), but that means *(Book(nil)) which is invalid, hence:
(*Book)(nil)
'nil' is to Go what NULL/null is to other languages like C#/Java, etc. The *Variable is just getting the pointer value for the Book object of Model.
So in this case, I believe what's happening here is that (*Book)(nil) is setting the pointer value of the Book object of the Model to nil(/null).
Hope this helps in some way. 😊
Good Resource: https://go101.org/article/nil.html
This question already has answers here:
Multiple values in single-value context
(6 answers)
Closed 4 years ago.
The following is what I want to achieve
fmt.Println(string(ioutil.ReadAll(res.Body)))
But this throws the following error.
multiple-value ioutil.ReadAll() in single-value context
I know that ioutil.ReadAll() returns the bytes and the error. But I don't want to write an extra line as follows
bytes, _ := ioutil.ReadAll(resp.Body)
Is it possible to just pass the result of ioutil.ReadAll() to fmt.Println() if don't care abut error handling in Go?
If you want it only once, it makes little sense in my opinion. However if this is a common situation and you feel that it improves code readability a lot, try something like:
// perhaps, there's a better name for this
func resultToString(b []byte, _ error) string {
return string(b)
}
// and later:
fmt.Println(resultToString(ioutil.ReadAll(res.Body)))
Unfortunately, that's a string-specific function, so for any other type you'll need to duplicate it.
This question already has answers here:
What does an underscore and interface name after keyword var mean?
(2 answers)
Closed 5 years ago.
I was reading DigitalOcean's golang client. I noticed that they create an instance of their *Op struct in a _ variable. Example:
https://github.com/digitalocean/godo/blob/master/droplets.go#L32
var _ DropletsService = &DropletsServiceOp{}
Why is this line needed?
This line is a compile time check that *DropletsServiceOp satisfies the DropletsService interface.
The line has no effect on the execution of the program.
If you look at the blame on that file, at that line, you get a clue:
https://github.com/digitalocean/godo/blame/master/droplets.go#L32
It does a compile-time check that *DropletsServiceOp satisfies the DropletsService interface. Prior to the commit introducing that, they were doing this in their test suite.