Go comma ok idiom - How & When to Use?

Introduction to GO comma ok idiom

Go is a very good language when it comes to testing different features or data in Go programs. Unlike other languages like Python that have the try catch error handling pattern, Go uses the famous comma ok pattern. The comma ok pattern is used to test certain statements in our code so that we can minimize developing programs that do things they are not intended to do.

In this article we are going to dive into situations that are ideal for using the comma ok pattern. To make the best out of this article, you should have the basics of the Go language. If not please read the Introduction to Go from the official website. The Go comma ok idiom  is mostly used to :

Advertisement
  1. Test for error on a function return
  2. Testing if a key-value item exist in a Go map
  3. Testing if an interface variable is of certain type
  4. Testing if a channel is closed

 

Testing for errors on a function return

The comma ok idiom is most of the time used with functions that return more than one value, and one of the values is an error. Since there is no try catch pattern in Go, Go errors are treated as normal variables after being returned from a function. Consider a function that takes an integer as an argument and  returns an error if a number is odd.

Example

package main
 
import (
   "errors"
   "fmt"
)
 
func main() {
   num := 4
   if ok, err := isEven(num); ok {
       fmt.Printf("%d is divisible by 2 : %v \n", num, ok)
   } else {
       fmt.Println(err)
   }
}
 
func isEven(num int) (bool, error) {
   if num%2 != 0 {
       return false, errors.New("Number not divisible by 2")
   }
   return true, nil
}

Explanation

In the above example, we define the isEven() function that takes an integer as an argument and returns boolean and an error. This function body checks if a number is divisible by 2 . This function will return a false boolean and an  error if the test fails, otherwise it will return a true boolean and a nil for the error.

In the main function, we use the if statement to create the comma ok pattern. The used syntax is ,

if ok, err := isEven(num); ok

Advertisement

Since the isEven() function returns two values, the values in the left side of the assignment are the ok and err. The ok variable stores the boolean value returned from the function. The err variable stores the error in case err is not nil. Immediately after the function call , we have a semicolon and the ok variable. At this point, we are checking if ok is true and execute the code in the block.

Output

$ go run main.go
4 is divisible by 2 : true

 

Testing if a key-value item exist in a Go map

The  comma ok idiom can also be used to check if a key exists in a Go map. A Go map is made up of key value pair and the comma ok idiom will return true value if a key exists, else false.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   httpConnection := map[string]string{
       "url":    "https://www.golinuxcloud.com/",
       "method": "POST",
   }
   if v, ok := httpConnection["method"]; ok {
       fmt.Printf("Value is : %s \n", v)
   } else {
       fmt.Println("Key not found")
   }
}

Explanation

In the above example,  we initialize a map httpConnection with key value pairs of type string. The comma ok idiom has been used to check if the “method” key exists in the map. The v variable stores the value found in the httpConnection map if the key exists in the map. Otherwise the v variable will store nil while the ok variable stores false.

Output

$ go run main.go
Value is : post

 

Testing if an interface variable is of certain type

While writing code , it is important to always understand the type of data you are working with. Go offers type assertion which provides access to an interface value underlying a concrete value. The comma ok idiom can be used with type assertion to check if a value is of a certain type or not.

Example

package main
 
import (
   "fmt"
)
 
func main() {
   var v interface{} = 23
   if s, ok := v.(string); ok {
       fmt.Println(s, " is a string")
   } else {
       fmt.Printf("Variable type is %T\n", v)
   }
}

Explanation

In the above example, we define a variable v of any type. This means it can be assigned to any type in Go such as a string, bool, int and so on. The comma ok idiom has been used here to check if variable v is a string i.e if s, ok := v.(string); ok .In this example, variable s will store the value being checked if the returned value for the ok variable is true.

Output

Advertisement
$ go run main.go
Variable type is int

 

Testing if a channel is closed

The comma ok idiom is useful when working with Go channels. Channels in Go are like pipelines that allow data to pass through them from a sender to a receiver. The sender is always responsible for closing the channel and we can test this using the comma ok idiom.

Example

package main
 
import (
   "fmt"
   "time"
)
 
func main() {
   companyChannel := make(chan string)
   companies := []string{"Golinuxcloud", "Facebook", "Google"}
 
   go func() {
       for _, c := range companies {
           companyChannel <- c
       }
       close(companyChannel)
   }()
 
   go func() {
       for i := 0; i < 5; i++ {
           if name, ok := <-companyChannel; ok {
               fmt.Println(name)
           } else {
               fmt.Println("Channel closed!")
           }
       }
   }()
   time.Sleep(time.Second * 3)
}

Explanation

In the above example, we define a channel(companyChannel) of type string and an array of string values(companies).  We then spin a goroutine that loops through the company name and sends the names into the companyChannel. We close the companyChannel after we are done looping.

We then spin another goroutine that loops through integer values.Please note that the number of loops here exceeds the number of names in the companies slice. For each loop , we check if the companyChannel is closed using the comma ok idiom. If the channel is closed, we  print “Channel closed” in the terminal.

Output

Advertisement
$ go run main.go
Golinuxcloud
Facebook
Google 
Channel closed! 
Channel closed!

 

Summary

In this article we learn about Go comma ok idiom and how it has been used in different situations in our code. The comma ok idiom is commonly used to test if a function returns an error, test if a key exists in a map, test if a variable is of a certain type using type assertion and lastly testing if a channel is closed.

 

Further Reading

Effective GO

 

Categories GO

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X