Login Register


Golang Tutorial #2 - numbers and maps, conditions, structs, and types and interfaces filter_list
Author
Message
Golang Tutorial #2 - numbers and maps, conditions, structs, and types and interfaces #1
Continuing on with the series from yesterday, this is part 2 of the basic(ish) Go tutorials. Part 1 can be found here.

With no extra introduction, here's today's first topic - ints and floats

Ints and Floats

Unlike python, which has embedded, dynamic typesetting, Go requires the user to supply bit length as well as values for anything that isn't just "int" or "float" (i.e., unsigned, over the default max [which I think is 32 bits]). These types, along with their maximum values and descriptions are listed below (from https://golang.org/ ).
Code:
uint8 the set of all unsigned 8-bit integers (0 to 255) uint16 the set of all unsigned 16-bit integers (0 to 65535) uint32 the set of all unsigned 32-bit integers (0 to 4294967295) uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615) int8 the set of all signed 8-bit integers (-128 to 127) int16 the set of all signed 16-bit integers (-32768 to 32767) int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) float32 the set of all IEEE-754 32-bit floating-point numbers float64 the set of all IEEE-754 64-bit floating-point numbers complex64 the set of all complex numbers with float32 real and imaginary parts complex128 the set of all complex numbers with float64 real and imaginary parts byte alias for uint8 rune alias for int32

Maps

A map in Go is the same as a HashMap in Java, a dictionary in Python, a table in Lua, or a Hash in Ruby. Maps are flexible, easy to use, and don't have an allocated memory value (even when set with make(). It doesn't throw an error, but everything starts acting a bit odd).

Map examples:
Code:
// inline, structured map creation myMap0:=map[string]int{ "foo": 1, "bar": 2, //<-- not a typo, you need the last comma } // "indexed" map creation myMap1:=map[string]int{} myMap1["foo"]=1 myMap1["bar"]=2 // map-ception myMap2:=map[string]map[string]int{} // already initialized as map[string]int, so no use of := myMap2["foo"]=map[string]int{ "test": 1, "hello": 2, } myMap2["bar"]=map[string]int{ "abc": 3, "def": 5, }

Conditionals

Conditional control flow and logical operation in Go is similar to that of C, Java, Javascript, or almost any braced language (minus the parentheses). They're all fairly simple, so I'll just go over them below.

Logical operators:
Code:
|| - or - one or both of the conditions are true && - and - both variables are true ! - not - reverses the boolean value of a condition
Note: Go doesn't have any other superfluous logical operators, but any others (XAND, XOR, etc..) can be made with or, and, and not)

Conditionals:
Code:
// variables a,b,c:=true,true,false // if/else if/else block if a&&c{ // true and false = false, so this code isn't run }else if !a||c{ // not true (false) or false = false, so this isn't run, either }else if a||b{ // true or true = true, so this code is run }else{ // if nothing else worked, run this }

A quick final tip with anything conditional: some functions return errors as well as their desired value, so you can use semicolons to get the function returns, discard the error, and evaluate the return in the same line.
Code:
// boo, more code (underscore as variable means discard the value) boolValue,_:=multiReturnFunction() // lets say this returns bool, error if boolValue{ // <insert code here> } // yay, refactors! if boolValue,_:=multiReturnFunction();boolValue{ // <insert code here> }

Types

Types in Go are extremely easy to make and use using interfaces (which we'll discuss next) or by using pre-defined types. Examples of user-defined types are below.

Code:
// string container type. This is actually useful later type stringContainer string // int slice container type intSlice []int

I mentioned that container types are useful, because you can't use type association on non-user defined types (this includes types not defined in the current package). If, say, you wanted an associated repeat method for strings, you would associate with the string container type.
Code:
package main import "fmt" type stringContainer string // associate with stringContainer, accept an int as an argument, and return a string called res func(s stringContainer) repeatString(times int) (res string){ // add s to res "times" times for i:=1;i<=times;i++{ res=res+string(s) } // return res return } func main(){ str:=stringContainer("foo") fmt.Println(str.repeatString(3)) }

Structs

Structs in Go work similar to those in Ruby (except without symbols, which is nice[?]). Below is a basic example.

Code:
package main import( "fmt" "math/rand" ) type structEx struct{ id int randomVal int } func main(){ // set a, b, and c to structEx structs // inline struct initialization a:=structEx{0,rand.Intn(10)} // attribute init b:=structEx{} b.id=1 b.randomVal=rand.Intn(10) // inline attribute init c:=structEx{id: 2,randomVal: rand.Intn(10)} //print a and b fmt.Println("id","\t","val") fmt.Println(a.id,"\t",a.randomVal) fmt.Println(b.id,"\t",b.randomVal) fmt.Println(c.id,"\t",c.randomVal) }

Structs, when used in conjunction with types, can be used to bypass interface type errors (you can't have functions for interface types)
Code:
package main import "fmt" // raw object type (can't define functions) type object interface{} // struct container for interfaces type container struct{data interface{}} // function to extract data from a container struct func(c container) extract() interface{}{ return c.data } func main(){ // set a to an object within a container a:=container{object("test")} // print the extracted data fmt.Println(a.extract()) }

Interfaces

An interface, in its simplest description, is a "named collection of method signatures" (https://gobyexample.com ). What this means (and what you'll see looking pretty much anywhere) is that an interface is more or less a conditional that accepts values who's type matches at least all of the method signatures. A few examples of interfaces are below.

Empty interface container:
Code:
package main import( "fmt" "reflect" ) type object interface{} func main(){ i:=10 // set i to int obj:=object(i) // set obj to an object instance of i // print value and type fmt.Println(i,reflect.TypeOf(i)) fmt.Println(obj,reflect.TypeOf(obj)) }

From running this, we can see that an interface retains the original type (when reflect.TypeOf() is called on obj, it still returns int.

Here's a more complicated, structured example:
Code:
package main import "fmt" /* a type, sliceSum, accepts values of types with a sum() function that returns a float32 value */ type sliceSum interface{ sum() float32 } // container types for float32 and int slices type floatSliceCont []float32 type intSliceCont []int // sum function for float slice container func(c floatSliceCont) sum() (total float32){ for _,i:=range c{total+=i} return } // sum function for int slice container func(c intSliceCont) sum() (total float32){ for _,i:=range c{total+=float32(i)} return } func main(){ // set a and b to float and int slice containers a:=floatSliceCont{3.14,2.71,9.9} b:=intSliceCont{10,15,25} // set sumA and sumB to sliceSum instances of a and b sumA:=sliceSum(a) sumB:=sliceSum(b) // print the sums of sumA and sumB fmt.Println(sumA.sum(),sumB.sum()) }

End note: I didn't cover packages in this tutorial, because that in itself is a broad topic and there's already a lot in this thread, so I'll cover it next time.
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.

Reply





Messages In This Thread
Golang Tutorial #2 - numbers and maps, conditions, structs, and types and interfaces - by Inori - 04-20-2016, 03:24 PM



Users browsing this thread: 1 Guest(s)