Monthly Archives: June 2017

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