BinaryWebPark

A Simple Program to Help You Go From Ruby To Go

July 06, 2015

Dabbling With the Go Programming Language

With the rise of Go, I’ve been dabbling with it more and more. If you’re a Rubyist and you’re wondering how to setup Golang on your system, check out my article Setting Up Golang Like a Rubyist.

The High Level Basics

Here’s a few things that are helpful to know as you’re starting Go:

  • Go has a built in testing package
  • There’s a precise directory structure you must obey (covered in Setting Up Golang Like a Rubyist.)
  • There are no classes in Go, but you can have Structs
  • The else in an if/else statement goes right after the ending curly brace as follows:
if flag==true {
  //some code
} else {
  //some code
}

A Sample Problem to Walk Through

Here I’m going to implement a function to determine if a string’s characters are all unique. The function will return true if the string contains only unique characters and false otherwise.

The Golang Code

Below is the source code for a naive implementation of a function that solves the problem.

arraysandstrings.go

package arrays_and_strings

import "strings;

func uniqueString(s string) bool {

  var (
    flag bool = true
  )

  for _, r := range s {

    if strings.Count(s, string(r)) > 1 {
      flag = false
    }
  }

  return flag
}

The Golang Test Code

Below is the code that tests the source code in arrays_and_strings.go.

arraysandstrings_test.go

package arrays_and_strings

import (
  "testing"
)

func TestUniqueStringCharacters(t *testing.T) {

  got := uniqueString("abcdxyz")

  if got == false {
    t.Fatalf("uniqueString failed")
  }
}

func TestDuplicateStringCharacters(t *testing.T) {

  got := uniqueString("aabcdxyz")

  if got == true {
    t.Fatalf("uniqueString failed")
  }
}

A Few Words About The Test Code

You’ll notice the t *testing.T parameter. This appears to be the default structure for tests in Go. It enables you to output a failure message if the test fails. This is useful to know if you’re practicing test driven development (i.e., write a failing test first, then make it pass).

Differences from testing in Ruby

The other observation to point out is that the Go testing framework appears to not let you print messages using its fmt.Println statement (which is basically like puts in Ruby) when running tests.

For example, I tried:

func TestDuplicateStringCharacters(t \*testing.T) {
  got := uniqueString("aabcdxyz")
  if got == true {
    t.Fatalf("uniqueString failed")
  } else {
    fmt.Println("test passed")
  }
}

This is an example of Go enforcing strict configuration. I’m not sure how I feel about it, but it’s a definite change from the flexibility of Ruby.

I do like the fact that Go compiles down to any system, and because it’s a compiled language, right out of the box you’re going to much better performance than an interpreted language such as Ruby. But I still like Ruby anyway. After all, I could have solved the problem in Ruby with the following one line snippet in a method:

def char_uniq?(sample_string = "aBcdE")
  ("a".."z").none? {|c| sample_string.downcase.count(c) > 1 }
end