Wednesday, March 24, 2021

Top 10 Common Mistakes In Go Programming

 


Go is a popular and  trendy programming language. But Go developers often face particular common bugs and errors. Developers address them as Gotchas. Golang is a comparatively new programming language by Google. Native gophers often face these pitfalls, so here we came with some common mistakes and its solutions. Checkout the following Gotchas and if you have already come across them in Go programming journey, know the solutions of it.

Top 10 Common Mistakes In Go Programming-

1. Multiple-value in single-value context-

Issue-

 t  := time.Parse(time.RFC3339, “2018-04-06T10:49:05Z”)
fmt.Println(t)
../main.go:9:17: multiple-value time.Parse() in single-value context

When you try to parse the date and time, you get a compiler error.

Solution-

 t, err := time.Parse.RFC3339, “2018-04-06T10:49:05Z”)
  if err != nil {
      // TODO: Handle error.
}
fmt.Println(t)
2018-04-06 10:49:05 +0000 UTC

The parse function with time returns a time value and error value, and explicitly you need to use them. Or To ignore the unwanted error values, you can use a blank identifier _as below:

 m := map[string]float64{“pi”: 3.1416}
_, exists := m[“pi”] // exists == true

2. Possibly undesired value being used in goroutine-

Range variables in a loop are reused at each iteration; so, a goroutine created in a loop will point to the range variable from upper scope. In this way, the goroutine could use the variable with an undesired value. As per the below example, value of index and value used in goroutine are from the outer scope because goroutines run asynchronously, the value of index and value could be (and usually are) different from the intended value.

mySlice := []string{"A", "B", "C"}
for index, value := range mySlice {
go func() {
fmt.Printf("Index: %d\n", index)
fmt.Printf("Value: %s\n", value)
}()
}

To overcome this problem, a local scope should be created, like in the example below.

mySlice := []string{"A", "B", "C"}
for index, value := range mySlice {
  index := index
 
   value := value
go func() {
fmt.Printf("Index: %d\n", index)
fmt.Printf("Value: %s\n", value)
}()
}

Another approach to deal with this could be by passing the values as args to the goroutines.

mySlice := []string{"A", "B", "C"}
for index, value := range mySlice {
go func(index int, value string) {
fmt.Printf("Index: %d\n", index)
fmt.Printf("Value: %s\n", value)
}(index, value)
}

3. Nil pointer dereference-

Most of the time Go-developers face the issue of dereferencing of a nil pointer. Let’s check the issue-

 type Point struct {
     X, Y float64
}
Func (p *Point) Abs() float64 {
         Return math.Sqrt(p.X*p.X + p.Y*p.Y)
}
 func  main() {
            var p *Point
           fmt.Println(p.Abs())
}
Panic: runtime error: invalid memory address or nil dereference [signal] SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0xd2c5a]
 
goroutine 1 [running]:
main.(*Point).Abs(...)
         ../main.go:6
main.main()
        ../main.go:11 +0x1a 

Pointer in the main function (p) is nil, so you can not follow the nil pointer as it causes run-time error.

Solution-

func main() {
         var p *Point = new(Point)
         fmt.Println(p.Abs())
}

Either you can create a new Pont as mentioned in above snippet. Or Methods with pointer receivers either need a value or a pointer, so try this-

func main() {
var p Point //has zero value Point{X.0, Y.0}
fmt.Println(p.Abs())
}

4. Regular expression mismatch-

Know more at- https://solaceinfotech.com/blog/top-10-common-mistakes-in-go-programming/

No comments:

Post a Comment