I declare some variables (offsetI and limitI) outside of a conditional statement. Inside the conditional statement I am trying to assign them values, then use those values for a query after the conditional statement.
var (
number, size, offset, limit string
offsetI, limitI uint64
)
// Get the string values for number, size, offset, and limit
// ...
if size != "" {
// Parse the number value
numberI, err := strconv.ParseUint(number, 10, 64)
if err != nil {...}
// Parse the size value
limitI, err = strconv.ParseUint(size, 10, 64)
if err != nil {...}
// Calculate the offset
offsetI = numberI * limitI
} else {
// Parse the limit value
limitI, err := strconv.ParseUint(limit, 10, 64) // limitI declared and not used
if err != nil {...}
// Parse the offset value
offsetI, err = strconv.ParseUint(offset, 10, 64)
if err != nil {...}
}
// Make the query using offsetI and limitI
result, err := s.GetAllPaginated(offsetI, limitI)
if err != nil {...}
I am not intending to re-declare the limitI variable in the scope of the else statement, but I need to use the := operator for declaring a new err variable.
The only thing I could come up with was to separately declare another err variable, so I could use a regular assignment statement:
} else {
var err error // New
// Regular assignment statement now
limitI, err = strconv.ParseUint(limit, 10, 64)
if err != nil {...}
I would like to be able to do this without having to declare an additional error variable.
The extra var error is awkward, but it's a common way to address this situation. The spec on scoping says (emphasis mine):
The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.
So in your case, that short variable declaration is declaring a different limitI scoped to the "innermost containing block." Since it only "lives" until the next closing brace, it isn't used.
In your specific case, an option might be to declare err outside the if/else, since it's used in both inner scopes, so you can use use = instead of := with those functions returning errors. Then there's no "inner limitI" declared and you have no unused variable issue.
"Shadowing" situations like this can also produce unexpected behavior rather than an error. go vet -shadow tries to detect "[v]ariables that may have been unintentionally shadowed" and, different but related, gordonklaus/ineffasign generalizes the "unused variable" check to detect useless assignments even if they weren't declarations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With