Variant Types in Golang

Here we Go again…

I had corresponded with some seasoned Go programmers about variant types some time ago.  I was searching for a way to keep a slice of data where each element might be a different data-type.  The approach I had been taking was in trying to define a data-structure that could act as a wrapper for some of the basic data types.  I then learned through the wisdom of these developers that Go could already accommodate my needs in a much simpler fashion.

The interface is a facet of the Go programming language that allows one to define a set of behaviors (methods) that one may associate with any data-type.  If one defines no behaviors/methods, the variable associated with the empty interface can assume any type.

Please consider the following program:

typetest1.go

// Copyright 2013 - by Jim Lawless
// License: MIT / X11
// See: http://www.mailsend-online.com/license2013.php
//
// Bear with me ... I'm a Go noob.

package main

import (
   "fmt"
)

var x interface{}

func main() {
   x=5
   i,ok := x.(int)
   if ok {
      fmt.Printf("x holds the integer value %d\n\n",i)
   }

   x="testo"
   var s=x.(string)
   fmt.Printf("The string value of x is now %s\n\n",s)

   x=5
   fmt.Printf("The runtime value of x is now %v\n\n",x)
}

The code initially defines a variable x as an implementer of an empty interface.  The code then assigns the integer constant 5 to x.

The next portion of code tries to obtain an integer value from x into the integer variable i.  The boolean variable ok will contain true if the conversion to integer was successful.  The code will next test the conversion with the ok variable and can then print the integer if the conversion had been successful.

We see in the running output…

x holds the integer value 5

…indicating that the conversion has been a success.

In the next portion of code, a string constant is assigned to x. The code then attempts to print the contents as a string value.  We see the output…

The string value of x is now testo

…indicating that the code was able to assign a string to a variable that had previously referred to an integer.

The final line of output in the code uses the %v formatting symbol to convert the variable to a displayable value regardless of the type.  The code again assigns the integer value 5 to the variable x and calls fmt.Println().  The yielded output is:

The runtime value of x is now 5

My original need was to define a slice of variant data.  Please consider this short program that keeps a string constant, an integer constant, and a boolean constant in a slice defined with empty interface characteristics:

typetest2.go

// Copyright 2013 - by Jim Lawless
// License: MIT / X11
// See: http://www.mailsend-online.com/license2013.php
//
// Bear with me ... I'm a Go noob.

package main

import  (
   "fmt"
)

var cells []interface{}=[]interface{}{ "x",124,true }

func main() {
   for i:=0; i<len(cells) ; i++ {
      fmt.Printf("Item %d ",i);
      switch( cells[i].(type) ) {
         case int:
            fmt.Printf("int :  %d\n",cells[i].(int))
            break;
         case string:
            fmt.Printf("string : %s\n",cells[i].(string))
            break;
         case bool:
            fmt.Printf("bool : %t\n",cells[i].(bool))
            break;
      }
   }
}

The code defines a variable named cells as a slice of items that implement the empty interface. Each element of the slice can then assume a different data-type.

The output yielded by the above code is:

Item 0 string : x
Item 1 int :  124
Item 2 bool : true

I hope to be able to use these concepts in newer programs, soon.

UPDATE 5 July, 2013: Please see Ralph Corderoy’s cleaner version here:

http://play.golang.org/p/1QhJ_M4ZOh

Advertisements

About Jim Lawless

I've been programming computers for about 36 years ... 30 of that professionally. I've been a teacher, I've worked as a consultant, and have written articles here and there for publications like Dr. Dobbs Journal, The C/C++ Users Journal, Nuts and Volts, and others.
This entry was posted in Programming and tagged . Bookmark the permalink.

9 Responses to Variant Types in Golang

  1. Christophe Meessenmike says:

    Thank you for this very helpful blog post. In my case I have to save and restore a sequence of operations encoded in JSON. Operations differ by argument number and types. Your blog gives me a very good start.

  2. John says:

    Unfortunately go does not have ADTs, so yes, if you want to store multiple types in a data structure you have to resort to interfaces, often interfaces. However it does throw type safety out of the window in a lot of places (type assertions, anyone?).

    I guess the language authors tried to keep Go small and simple.

  3. Have a look at http://play.golang.org/p/1QhJ_M4ZOh for a more idiomatic version. Using := to avoid the Java-esque double-definition. `break;’ isn’t needed. Iterate over a slice with range. Read http://golang.org/doc/effective_go.html for more tips.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s