Golang的if语句无法识别int32类型的0。

huangapple go评论121阅读模式
英文:

Golang if statement not seeing 0 for int32

问题

我有一个用golang编写的proto3/grpc函数。在一个switch语句中,if语句无法将int32的值0视为0。我在之前打印了该值,确实是0,但是if语句仍然执行。在我的代码中,我在注释中给出了输出。我知道对于int类型,nil值是0。如果我为lname和fname设置一个值,它们会按预期工作。非常感谢任何帮助。以下是我的输出:

  1. map[fname: lname: email: id:0]
  2. 0
  3. id = $1

以下是我的代码:

  1. func (s *server) GetUsers(ctx context.Context, in *userspb.User) (*userspb.Users, error) {
  2. flds := make(map[string]interface{})
  3. flds["id"] = in.Id // 0
  4. flds["fname"] = in.Fname // "" (空)
  5. flds["lname"] = in.Lname // "" (空)
  6. flds["email"] = in.Email // "" (空)
  7. fmt.Println(flds) //map[lname: email: id:0 fname:]
  8. var where bytes.Buffer
  9. n := 0
  10. for _, v := range flds {
  11. switch v.(type) {
  12. case string:
  13. if v != "" {
  14. n++
  15. }
  16. case int, int32, int64:
  17. if v != 0 {
  18. n++
  19. }
  20. }
  21. }
  22. calledvariables := make([]interface{}, 0)
  23. i := 1
  24. for k, v := range flds {
  25. switch v.(type) {
  26. case string:
  27. if v != "" {
  28. if i != 1 {
  29. where.WriteString(" AND ")
  30. }
  31. ist := strconv.Itoa(i)
  32. where.WriteString(k + " = $" + ist)
  33. calledvariables = append(calledvariables, v)
  34. i++
  35. }
  36. case int, int32, int64, uint32, uint64:
  37. /////// 这个if语句有问题(v打印的值是0,但它在if语句中)
  38. if v != 0 {
  39. fmt.Println(v) // 0
  40. if i != 1 {
  41. where.WriteString(" AND ")
  42. }
  43. ist := strconv.Itoa(i)
  44. where.WriteString(k + " = $" + ist)
  45. calledvariables = append(calledvariables, v)
  46. i++
  47. }
  48. }
  49. }
  50. fmt.Println(where.String()) // id = $1
  51. ...
英文:

I have proto3/grpc function written in golang. There is a if statement written in a switch that does't see an int32 as a value of 0 when the value is a 0. I print the value before and it's a 0 but the if statement runs anyway. In my code below I have the output in a comment. I know for a int the nil value is a 0. If I place a value for the lname, fname they work as it should. Any help appreciated. Here is my output:

  1. map[fname: lname: email: id:0]
  2. 0
  3. id = $1

Here is my code:

  1. func (s *server) GetUsers(ctx context.Context, in *userspb.User) (*userspb.Users, error) {
  2. flds := make(map[string]interface{})
  3. flds["id"] = in.Id // 0
  4. flds["fname"] = in.Fname // "" (empty)
  5. flds["lname"] = in.Lname // "" (empty)
  6. flds["email"] = in.Email // "" (empty)
  7. fmt.Println(flds) //map[lname: email: id:0 fname:]
  8. var where bytes.Buffer
  9. n := 0
  10. for _, v := range flds {
  11. switch v.(type) {
  12. case string:
  13. if v != "" {
  14. n++
  15. }
  16. case int, int32, int64:
  17. if v != 0 {
  18. n++
  19. }
  20. }
  21. }
  22. calledvariables := make([]interface{}, 0)
  23. i := 1
  24. for k, v := range flds {
  25. switch v.(type) {
  26. case string:
  27. if v != "" {
  28. if i != 1 {
  29. where.WriteString(" AND ")
  30. }
  31. ist := strconv.Itoa(i)
  32. where.WriteString(k + " = $" + ist)
  33. calledvariables = append(calledvariables, v)
  34. i++
  35. }
  36. case int, int32, int64, uint32, uint64:
  37. /////// THIS IF STATMENT IS THE ISSUE the ( v is printing the value of 0 and it's in the if statement )
  38. if v != 0 {
  39. fmt.Println(v) // 0
  40. if i != 1 {
  41. where.WriteString(" AND ")
  42. }
  43. ist := strconv.Itoa(i)
  44. where.WriteString(k + " = $" + ist)
  45. calledvariables = append(calledvariables, v)
  46. i++
  47. }
  48. }
  49. }
  50. fmt.Println(where.String()) // id = $1
  51. ...

答案1

得分: 5

因为字面量0不是相同的类型。如果你这样写:

  1. if v != int32(0) {

当值是int32类型时,它会按预期工作。不幸的是,你将所有的整数类型组合在一个case中,这将使得正确处理这个问题变得困难/不便。你可以尝试使用反射,在运行时将值与其类型的零值进行比较,使用reflect.Zero

英文:

Because the literal 0 is not the same type. If you do:

  1. if v != int32(0) {

When the value is an int32, it works as expected. Unfortunately, you're combining all the int types in a single case, which will make this difficult/unwieldy to handle correctly. You could probably work something out using reflection to compare the value against the zero value for its type at runtime, using reflect.Zero.

huangapple
  • 本文由 发表于 2017年5月30日 21:16:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/44263381.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定