Category Archives: Go

Anonymous fields in Go

Anonymous fields in Go structures allow us to shortcut dot notation as well as allow us to use compositions to add methods to a type.

Shortcutting the dot notation

For example if we have something like this

type A struct {
	X int
	Y int
}

type B struct {
	Z int
}

type C struct {
	AValue A
	BValue B
}

then to access the field X on AValue we’d write code like this

c := C {}
c.AValue.X = 1

Changing the C struct fields to anonymous (i.e. removing the field name) like this

type C struct {
	A
	B
}

allows us to reduce the use of the dot notation and access X on A as if it was a field within the C struct itself, i.e.

c := C {}
c.X = 1

Okay, but what if B struct now replaced the Z field name with X, i.e.

type A struct {
	X int
	Y int
}

type B struct {
	X int
}

We now have a situation where both A and B have the same field name, well we can still use anonymous fields, but we’re back to using more dot notation again to get around the obvious field name conflict, i.e.

c := C {}
c.A.X = 1
c.B.X = 2

Initializers do not support shortcutting

Unfortunately we not get the advantage of the anonymous fields with the initializer syntax, i.e. We must specify the A and B structs like this

c := C{ A : A{2, 4}, B : B { 12 }}

// or

c := C{ A : A{X : 2, Y : 4}, B : B { Z: 12 }}

// but this doesn't compile
c := C{ X : 2, Y : 4, Z : 12 }
// nor does this compile
c := C{ A.X : 2, A.Y = 3, B.Z : 12 }

Composition

More powerful than the synaptic sugar of embedded/anonymous fields, we can also use composition to increase the methods available on the struct C. For example let’s now add a method to the A type which allows us to move our X, Y point

func (a *A) Move(amount int) {
	a.X += amount
	a.Y += amount
}

Now we can call the method on the previously declared c variable like this

c.Move(10)

We can also create further methods via a composition pattern on type C if we want using empty types, let’s assume we have type D and extend the composition of type C

type D struct {}

type C struct {
	A
	B
	D
}

now we can add methods to D and ofcourse they’ll be available as part of C. So for example, maybe D acts as a receiver for methods that serialize data to JSON, now our C type will also appear to have those methods.

REST services with Mux and Go

Mux is a “powerful URL router and dispatcher” for Go and that means it allows us to route REST style requests to produce REST/micro services.

Creating our service

Let’s start out by creating a very simple EchoService which will contain our service implementation.

In my code based I create a service folder and add a service.go file, here’s the code

Note: This creation of a new go file, interface etc. is a little over the top to demonstrate mux routes/handlers, but my OO roots are probably showing through. In reality we just need a simple function with an expected signature – which we’ll see later.

package service

type IEchoService interface {
	Echo(string) string
}

type EchoService struct {

}

func (EchoService) Echo(value string) (string, error) {
	if value == "" {
		// create an error
		return "", nil
	}
	return value, nil
}

We’ve created an interface to define our service and then a simple implementation which can return a string and an error. For now we’ll not use the error, hence return nil for it.

Before we move onto the Mux code which will allow us to route requests/responses, let’s create a bare bones main.go file

package main

import (
   "goecho/service"
)

func main() {
   svc := service.EchoService{}
}

At this point this code will not compile because we haven’t used svc.

Implementing our router

Before we get started we need to run

go get -u github.com/gorilla/mux

from the shell/command prompt.

Now let’s add the code to create the mux router and to create a server on port 8080 that will be used to connect to our router (and service). We’ll also include code to log any fatal errors (again this code will not compile as the previously created svc variable remains unused at this point)

package main

import (
   "goecho/service"
   "github.com/gorilla/mux"
   "log"
   "net/http"
)

func main() {

   svc := service.EchoService{}

   router := mux.NewRouter()

   // service setup goes here

   log.Fatal(http.ListenAndServe(":8080", router))
}

I think this code is pretty self-explanatory, so we’ll move straight on to the implementation of our route and handler.

I’m going to add the handler to the service package but this handler needn’t be a method on the EchoService and could just be a function in the main.go (as mentioned previously).

You’ll need to add the following imports

import (
   "net/http"
   "github.com/gorilla/mux"
)

and then add this method, which is the handler and will call into our EchoService method.

func (e EchoService) EchoHandler(w http.ResponseWriter, r *http.Request) {
   vars := mux.Vars(r)

   result, _ := e.Echo(vars["s"])

   w.WriteHeader(http.StatusOK)
   w.Write([]byte(result))
}

To allow us to call the EchoService Echo method we declare a variable e for the EchoService. The arguments, of types ResponseWriter and Request are required to decode a request and to allow us to write a response. In this example the mux.Vars will be used to get us part of the rest command/URL.

Again, we’re not bothering (at this point to worry about the errors, so result, _ is used to ignore the error.

Next we write a Status OK code back and write the result back as a byte array.

Obviously we now need to set up our handler in main.go, so replace the line

// service setup goes here

with

router.HandleFunc("/echo/{s}", svc.EchoHandler).Methods("GET")

this simply creates the route for calls onto http://<hostname>/echo/??? (where ??? is any value which gets mapped to the mux.Vars[“s”]) through to the supplied handler (svc.EchoHandler) using the GET method.

For example, navigating to http://localhost:8080/echo/HelloWorld in your preferred web browser should display HelloWorld.

We can add multiple routes/handlers, for example let’s create a handler to respond with “Welcome to the EchoService” if the user navigates to http://localhost:8080. Place this function in main.go

func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
   w.WriteHeader(http.StatusOK)
   w.Write([]byte("Welcome to the EchoService"))
}

and add this handler code before (or after) your existing handler code in main

router.HandleFunc("/", WelcomeHandler).Methods("GET")

Benchmarking code in Go

To create a unit test in Go<, we simple create a function with Test as the first part of the name, see my previous post on Unit testing in Go.

We can also write performance/benchmarking test code by creating a function with Benchmark as the first part of the function name, i.e. BenchmarkDataRead and it takes on the same format as a unit test, for example

func BenchmarkEcho(b *testing.B) {
	expected := "Hello"
	actual := test.Echo("Hello")

	if actual == expected {
		b.Error("Test failed")
	}
}

Our benchmark is passed a testing.B type which gives us functionality as per testing.T, in that we can fail a benchmark test etc. Obviously, for a benchmarking type, we also have the ability to start and stop the timer, for example if we have initialization and cleanup code we might want to exclude these from the benchmark by just wrapping the key code in a b.StartTimer and b.StopTimer section, i.e.

func BenchmarkEcho(b *testing.B) {
	expected := "Hello"

	b.StartTimer()
	actual := test.Echo("Hello")
	b.StopTimer()

	if actual != expected {
		b.Error("Test failed")
	}
}

Unit tests in Go

In the previous post I mentioned that the Go SDK often has unit tests alongside the package code. So what do we need to do to write unit tests in Go.

Let’s assume we have the package (from the previous post)

package test

func Echo(s string) string {
	return s
}

assuming the previous code is in file test.go and we then create a new file in the same package/folder named test_test.go (I know the name’s not great).

Let’s look at the code within this file

package test_test

import "testing"
import "Test1/test"

func TestEcho(t *testing.T) {
	expected := "Hello"
	actual := test.Echo("Hello")

	if actual != expected {
		t.Error("Test failed")
	}
}

So Go’s unit testing functionality comes in the package “testing” and our tests must start with the word Test and takes a pointer to type T. T gives us the methods to create failures etc.

In Gogland you can select the test_test.go file, right mouse click and you’ll see the Run, Debug and Run with coverage options.

Creating your own package in Go

When we import a library in Go we’re really importing a package. A package is created in a folder of it’s own and whilst you can name the folder anything you like, by convention we should name the folder the same as the package name that the files within the folder will be part of.

For example if our project is in the folder src/example and we want to create a package called conv (for converters) then this should be created in src/example/conv.

The files within this folder can be named anything you like and can have any package names, for example the Go source has a package context and it includes files as part of the package context but also package context_test, but ofcourse it makes sense that the code is all relevant to the package/folder it’s contained within – for example tests etc. might have a different package name to not pollute the package that the user/dev sees.

Let’s create a simple Echo function in a package named test, so off of our main.go folder we create a test folder and within this we have a test.go file and here’s the source

package test

func Echo(s string) string {
	return s
}

to use this package in our main.go file we import like this

package main

import "fmt"
import "Example/test"

func main() {
	fmt.Println(test.Echo("Hello"))
}

Notice the Example/test (our project name in Gogland) followed by the package folder name. The Example folder in this case is the folder that our main.go file is within.

References

How to Write Go Code contains a great overview of project, folder and package layouts for your Go application.

Interfaces and duck typing in Go

Go isn’t object oriented in the typical sense, i.e. if you’re coming from C#, Java or even C++, but it does offer some features which map to features often available in the OO world in one way or another.

For example in a previous post we saw how we created methods that mirror the syntax of methods on objects (or extension methods in C#). We also have interfaces in Go which can include functions.

For example

type Duck interface {
   Quacks()
}

But how do we implement an interface as we cannot include functions in types?

So with our knowledge of methods we will see how we can implement a type that conforms to an interface. As we are not “implementing” or otherwise inheriting from an interface we instead duck type the interface.

Duck typing comes from the phrase – if something looks like a duck, swims like a duck and quacks like a duck then it’s probably a duck.

In programming terms duck typing is the matching of types based upon expected methods and properties rather than upon an expected type. Therefore our Duck interface can be implemented by objects which don’t even need to know about the Duck interface.

For example

type Animal struct {
}

func (a Animal) Quacks() {
   fmt.Println("The animal quacks");
}

function Quack(duck Duck) {
   duck.Quacks()
}

func main() {
   a := Animal{}
   Quack(a)
}

So in the above we’ve declare an Animal type and create a method for the Animal type which is named Quacks (thus fulfilling the requirements of the Duck interface).

Next we have a function which takes a Duck and calls the Quack method on it.

But as you see within main, we’re actually able to pass an Animal type into the function which resolves to Duck because it supports the required interface. Hence duck typing.

Functions and Methods in Go

In the previous post on Go I’ve used the words method and function interchangeably, but as I learn more about Go I find that – in Go, methods and functions are actually different.

First off, let me point you to this post Part 17: Methods which covers this subject in more depth. But here’s the elevator pitch.

Methods names can be overloaded and the syntax of using a method is more like a method on an object.

Let’s look at a simple example, a classic sort of OO example. We have different shape types and each has an area method.

This is example is taken from Part 17: Methods

type Rectangle struct {
   length float64
   width float64
}

type Circle struct {
   radius float64
}

func (shape Rectangle) Area() float64 {
   return shape.length * shape.width
}

func (shape Circle) Area() float64 {
   return math.Pi * math.Pow(shape.radius, 2)
}

Notice that a method has the type declared before the method name (unlike a function) and this is because we call it in the way we would an extension method and object’s method in C#.

In Go the type declared after the function name (function syntax) is known as an argument, whereas a type declared before the function name (method syntax) is known as a receiver.

For example

r := Rectangle{ length = 100, width = 23 }
c := Circle { radius = 30 }

rArea := r.Area()
cArea := c.Area()

Starting out with Go

I like learning different programming languages. Sometime I learn alternate ways to do things which might be useful in my usual language, sometimes I get a feel for how another language might be better for certain tasks and gives me more options for developing apps. I recently started learning the language Go, so this is my first of several posts on what I’ve learned.

Note: I’m literally just learning this, so I suspect any posts on the subject will be pretty basic, but hopefully, might be of use to others (as well as myself).

Why Go?

Probably the first question many of us might ask is why pick a specific language. For example, is the language all about speed, or writing application in a specific paradigm like a functional language.

So Why Go? Where does it fit into?

Before we look to answer that question, we should note that Go was designed by Google as an open source, compiled and statically typed language.

So we might view Go as a possibly modern take on C but with features, such as concurrency as primitives as well as being a garbage collected language. It’s cross platform and compiles to native. The language is a general purpose language, so it can do many things, but I’ve not found anything to suggest it’s aimed at GUI work. I’ve seen lots of talk about supporting distributed code, and services/microservices etc. but not yet done anything with these, so cannot confirm how good it is as such things.

Let’s get started and download Go

Okay, so you can read a brief history of Go from Wikipedia etc., let’s instead download Go and install it from Downloads.

On Windows (as I’m currently running it) by default the installation is into C:\Go and this is what the environment variable %GOROOT% should be set to (either during installation or manually assigned if need be).

You’ll need to set up the %GOPATH% environment variable (or via your preferred IDE, I’m using JetBrains Gogland (1.0 Preview)) to point to your workspace, i.e. where you’ll be writing your application(s) to. So, for example, C:\Development\GoglandProjects on my installation is where I’m writing my Go projects to at the moment.

Note: You do seem to be able to get away without a GOPATH.

Hello World

Yes, this one’s on The Go Programming Language website, but we’ll recreate here.

  • In your workspace create a HelloWorld folder
  • Create the file hello-world.go in your preferred editor
  • Type into the file, the following
    package main
    
    import "fmt"
    
    func main() {
       fmt.Println("Hello World")
    }
    
  • From a command prompt (within the workspace\HelloWorld folder) run
    go build hello-world.go
    

    or even simpler (if you’re in the code’s folder), just run

    go build
    

    This command compiled the Go code into a native EXE

At this point you’ll have a binary (hello-world.exe) that you can run or if you delete this and run the following line from the command prompt in your workspace

go run hello-world.go

then Go will compiled to a temporary EXE, i.e. no EXE is create in our workspace, it just runs the go code.

In the hello-world.go code, you’ll see standard looking constructs, for example we have an include/import/using type line which imports the fmt package, you have a func main, which is obviously a function/method (and should be in a package named main) and some call on the fmt package which ouputs to the console the string “Hello World”.

So all pretty recognisable.

Note: I mentioned fmt is a package and at first site this appears to be like an object/class, but Go is not an object oriented language. There’s no inheritance for example, or base object but there are constructs that can give us some OO like capabilities, instead of objects we have structures “struct” types like in C as well as interfaces.

Basics

Here’s a quick list of some of the basics we expect to see in a language.

Commenting

The standard C++ // and /* */ operators are used for single line and multi line comments respectively.

Namespace/Package

Analogous to a namespace, we have the package – for example

package fmt

Creating your own types

As mentioned, Go is not an OO language, but like C with typedef and struct we can create our own custom types, for example

type MyInteger int

or a struct using

type MyStructure struct {
	a MyInteger
	b MyInteger
}

Declaring variables

We define variables using the var keyword (like the optional usage in C#), i.e.

var myInteger = 3

In the case of situations where we want to declare the type. We declare the type after the variable name, i.e.

var myInteger MyInteger = 3

We could also use

var myInteger = MyInteger(3)

Note: Interestingly, declaring an unused variable results in a compile time error as does unused packages, this ensure you keep your code “clean” of anything not required.

Basic types

Ofcourse Go includes the basic types (see builtin.go) which include string, int, unit, byte, float, bool etc.

Loops

Ofcourse we for loops (see below), but interestingly no while loops

for i := 0; i < 3; i++ {
   fmt.Println("Hello")
}

with the := reminds me of a Pascal crossed with C style. Notice no parenthesis are required around the for loop but braces are required.

Also parenthesis must be placed (opening parenthesis {) on the same line as the loop (of if statements).

Using a for loop like a while loop just means writing the following

i := 0
for i < 3 {
   fmt.Println("Hello")
   i++
}

A while(true) infinite loop can be written as

for {
   fmt.Println("Hello")
}

Flow control with if..else and switch statements

if i % 2 > 0 {
   fmt.Println(strconv.Itoa(i) + " Odd")
}

We can also declare/assign variables as part of the if statement, for example

if isOdd := i % 2; isOdd > 0 {
   fmt.Println(strconv.Itoa(i) + " Odd")
}

else statements must be on the closing brace line and their opening brace on the same line also, for example

if isOdd := i % 2; isOdd > 0 {
   fmt.Println(strconv.Itoa(i) + " Odd")
} else {
   fmt.Println(strconv.Itoa(i) + " Even")
}

Switch statements are pretty much as per C# etc.

switch i % 2 {
case 0:
   fmt.Println(strconv.Itoa(i) + " Odd")
default:
   fmt.Println(strconv.Itoa(i) + " Even")
}

like if statements, we can also assign variables and test them after the switch keyword and before the opening brace.

Functions

As mentioned already, we create functions using the func keyword. Functions can take arguments and return values (as you’d expect). For example

func isOdd(i int) bool {
	return i % 2 != 0
}

Note: we declare the return type after the function (or no type for the equivalent of a void function) and we use the return keyword as per many C like languages.

We can pass multiple arguments into a function in the standard way

func doSomething(i int, test bool) bool {
// do something
}

we can also group arguments of the same type like so

func doSomething(a, b, c int) bool {
// do something
}

We’ve shown code returning a single value, but we can also return tuples easily using the following syntax

func doSomething() (string, string) {
	return "Hello", "World"
}

and assigning this we would have something like

a, b := doSomething()

We can create anonymous functions using the func() syntax, for example

func doSomething() func() string {
	return func() string {
		return "Hello World"
	}
}

will return a function which returns a string.

We can also pass variable arguments to a function (like vargs or params) using

func doSomething(args ...string) {
	for _, arg := range args {
		fmt.Println(arg)
	}
}

Note: in this example the _ is used as range returns a tuple of index (int) and the value (i.e. value[index]), The _ can be used in situations where we want to ignore a value and is special in that it will not cause an unused variable compile time error.

Anonymous and named returns

In the above we looked at declaring return values like this

func doSomething() (string, string) {
	return "Hello", "World"
}

in that the return (string, string) has no variable name associated with it, but we can also return named variables, for example

func doSomething() (a string, b string) {
	return "Hello", "World"
}

at this point the named returns only really demonstrate a use as a form of documentation, but they also get automatically initialized to the defaults for the type and can be used in a similar way to the out keyword in C#, i.e. we can assign to them.

Here’s an example

func doSomething() (a string, b string) {
	a = "Hello"
	b = "World"
	return
}

so here we assign the named return a value and then we must still use a return. This allows us to build up the return tuple during the flow of the function, instead of storing as a local variable until we return the tuple.

Arrays

Let’s end this post with arrays. The standard [] syntax is used, here we declare an array and initialize it

a := [2]string{"Hello", "World"}

arrays are base 0 index, hence

fmt.Println(a[0]) 

will result in Hello output to the console.

Package visibility

Functions and methods with a capitalized first letter (i.e. Pascal case) are public, whereas a lowercase first letter (i.e. Camel case) are private to the package.

In other words the public functions are visible globally whereas private are visible only within the package.

References

The Go Programming Language
Go by example