770 likes | 1.06k Views
Go. Nathan Reale. Quick History. Developed by Rob Pike, Robert Griesemer, and Ken Thompson beginning in 2007 at Google Released in November 2009 as an open source project Go is still a work in progress, and new packages and features are being added weekly. Standard Data Types.
E N D
Go Nathan Reale
Quick History • Developed by Rob Pike, Robert Griesemer, and Ken Thompson beginning in 2007 at Google • Released in November 2009 as an open source project • Go is still a work in progress, and new packages and features are being added weekly Go - Nathan Reale
Standard Data Types • Standard Types: bool, int, float • Array/Slice • String (no general char type) • Pointer • Map • Struct • Function • Interface • Channel Go - Nathan Reale
Numeric Types • uint8, uint16, uint32, uint64 • int8, int16, int32, int64 • float32, float64 • complex64, complex128 • Each system has the following predefined: • byte (character) • uint • int • float • complex Go - Nathan Reale
Numeric Types • Most type conversions must be given explicitly • On 32-bit systems, int is a 32-bit integer, and int32 is a 32-bit integer, but they are actually different types • It is easy to convert between different types someUint := uint(someInt) Go - Nathan Reale
Declaration of Variables • Variables are declared with the “var” keyword • newly declared variables are initialized to 0 var counter int counter = 10 • If a variable is initialized, the type can be inferred var counter = 10 • A variable can also be declared and initialized in a condensed form counter := 10 Go - Nathan Reale
Declaration of Variables • A var block can be used to declare multiple variables at once var ( counter int index = 10 name = “GO” ) Go - Nathan Reale
Multiple Assignment • Go supports multiple assignment val1, val2 := 1, 2 • This can be used to swap variables easily val1, val2 = val2, val1 Go - Nathan Reale
Type • The “type” keyword works similarly to typedef in C type intSlice []int type score float • Type is mainly used to declare structs and interfaces Go - Nathan Reale
Constants • The “const” keyword is used to declare number, string, and Boolean constants • The type will be implicitly inferred const seven = 7 • Constants are declared at compile time, so they can not reference runtime code, such as Math.sin() • Constants can be declared in blocks like regular variables Go - Nathan Reale
Constants • Literal values in Go are very high precision, until they are forced into a specific type const bigNumber = 1 << 100 // bigNumber == 1267650600228229401496703205376 const phi = 1.61803398874989 Go - Nathan Reale
Iota • When using a constant block, iota can be used to define enumerated constants easily • iota is initially 0 • Each newline or semicolon increments iota • Iota can be left off of subsequent lines const ( zero = iota one two three four ) Go - Nathan Reale
Arrays • Declaration var array1 [10]int var array2 [15]string • Each Array has a size identified with it, which can be retrieved with len() len(array1) == 10 • All values of the array are initialized to the zero value for its type Go - Nathan Reale
Arrays • Values can be accessed like C array[2] = array[4] • Unlike in C, arrays are values array3 = array4 // Copies entire array • Each type and size combination are distinct array1 := [10]int{} array2 := [20]int{} array1 = array2 // Will not work Go - Nathan Reale
Arrays • Arrays can be populated and declared at the same time array3 := [5]int{1, 2, 3, 4, 5} • Specific values of the array can be initialized array4 := [5]int{3:10} • If an array is being initialized, the size can be left out array5 := […]int{1, 2, 3, 4, 5} // len(array5) == 5 Go - Nathan Reale
Arrays • Because arrays are values, not references, a copy is passed to a function • One way around this is to pass a pointer to the array to the function Sum(&array1) • Arrays can also be declared with the new keyword, which returns a pointer to the array arrayPtr := new([10]string) Go - Nathan Reale
Arrays • Multi-dimensional arrays var chessBoard = new([8][8]int) • Values can be accessed as expected fmt.Println(chessBoard[3][4]) • Initializing a multi-dimensional array inline var chessBoard = [2][2]int{ [2]int{1, 2}, [2]int{3, 4}} Go - Nathan Reale
Slices • Slices are a reference to a part of an underlying array var slice1 []int • Generally used instead of arrays • The length can be retrieved with len(), and the capacity with cap() • A slice is ostensibly a struct containing a pointer into an array, a length, and a capacity Go - Nathan Reale
Slices • Slices can be declared to be a reference to a part of an existing array slice1 := array1[0:5] slice1 := &array1 • Can be declared without explicitly declaring an array var slice2 = []int{1, 2, 3, 4, 5} slice3 := make([]int, 5) Go - Nathan Reale
Slices • In Go, slices are used to create growable arrays that have very little overhead // Create a slice with a capacity of 100 names := make([]string, 0, 100) // Add a name to the slice length := len(names) names = names[0:length+1] names[length] = “Bill Gates” Go - Nathan Reale
Strings • Strings act like immutable byte arrays message := “Triangle - ⟁” • Individual elements can be accessed message[3] == ‘a’ • Slices can be taken from strings message[0:8] == “Triangle” • len(string) returns the length of the string Go - Nathan Reale
Pointers • Go has pointers, but no pointer arithmetic • There is no way to deallocate memory that is referenced by a pointer, so there is no way to get a have a NULL pointer • This provides safety while still having the power of pointers • Go handles most pointer operations, including automatically dereferencing the pointer Go - Nathan Reale
Maps • Maps are built in hash tables/dictionaries • The following maps from strings to int var map1 map[string] int • To initialize the map m1 := map[string]float{ “Pi”:3.1415 } m2 := make(map[string]float) • To access a value in the map pi := m1[“Pi”] Go - Nathan Reale
Maps • A common idiom in Go is “comma ok”, where a function returns 2 values, and the second is used as a status or error phi, ok := m1[“Phi”] • If ok is true, then the value was in the map, if ok is false, the value is not in the array, and the zero value is returned Go - Nathan Reale
Maps • Key-Value pairs are deleted from a map using a similar style, by passing false as a second argument to the assignment function m1[“Pi”] = 0, false // Delete “Pi” • len(map) returns the number of keys in the map Go - Nathan Reale
New vs Make • new() allocates memory on the heap and returns a pointer to the allocated item • make() returns an actual object that was created • While new is used to allocate memory and return a pointer, make is used to create more complex types such as slices, maps and channels Go - Nathan Reale
New vs Make • make([]int, 5, 10) creates an underlying array of size 10, with each value initialized to 0, and then creates a slice referencing the first 5 elements • The underlying array is automatically garbage collected when no slices are left referencing it Go - Nathan Reale
Structs • Structs are similar to C, but also take the place of classes • Structs can be declared and initialized together var date struct { month string; day, year int } • Usually, structs are tied to a type type Date struct { month string day, year int } Go - Nathan Reale
Structs • Structs can be declared like normal type var today Date today.month = “April” • Structs can also be allocated with new • This returns a pointer, but the fields can be accessed the same way tomorrow := new(Date) tomorrow.day = 10 Go - Nathan Reale
Structs • Struct literals are used to instantiate a struct with values • The field can be specified so values can be given in any order • It is also common to work with a pointer to a struct and not the actual struct today := &Date{month:“April” day:8 year:2010} // today.month == “April” Go - Nathan Reale
Structs • Inheritance is achieved by embedding another type inside struct • Fields can be added anonymously type Event struct { name string; Date } var christmas Event christmas.name = “Christmas” christmas.month = “December” christmas.day = 25 Go - Nathan Reale
Structs • A struct literal for the previous example would need to include the definition for the date struct epoch := Event{“The Epoch”, Date{ “January”, 1, 1970 }} • The anonymous fields actually have their type as their name fmt.Println(epoch.Date); Go - Nathan Reale
Control Structures - If • If is very similar to C if requests <= 0 { quit() } else { runTask() } • Parenthesis are not required around the condition, but the braces are required Go - Nathan Reale
Control Structures - If • An alternate form of the if statement includes an initialization statement if phi, ok := map[“Phi”]; ok { fmt.Printf(“Φ is %f\n”,phi) } else { fmt.Println(“Φ is not declared”) } Go - Nathan Reale
Control Structures – For • There are four forms of the for statement in Go • For acts like the standard C for for i:=0; i<10; i++ { fmt.Println(i) } Go - Nathan Reale
Control Structures – For • For acts like the C while sum := 1 for sum < 100 { sum += sum } Go - Nathan Reale
Control Structures – For • For acts like an infinite loop for { fmt.Println(time.Seconds) } Go - Nathan Reale
Control Structures – For • For acts like a foreach loop over an array or map values := make(map[string]int) sum := 0 for _, value := range values { sum += value } Go - Nathan Reale
Control Structures – Switch • Switch acts similarly to switch in C, but there are a few key differences • The value being switched on does not have to be a constant or an integer • There is no automatic fall through • The “fallthrough” keyword can be used to force fall through • There is another variant of switch without an argument that evaluates cases until one is found to be true Go - Nathan Reale
Control Structures – Switch switch input { case 1: fmt.Println(“One”) case 2: fmt.Println(“Two”) case 3: fmt.Println(“Three”) default: fmt.Println(“What?”) } Go - Nathan Reale
Control Structures – Switch • Like an if statement, switch statements can have an initializing statement • There is a form of switch with no argument and each case is evaluated until a true case is found switch { case a<10: fmt.Println(“Less Than 10”) case a==10: fmt.Println(“10”) case a>10: fmt.Println(“More Than 10”) } Go - Nathan Reale
Switch to Determine Type • There is a special idiom to determine the type of a variable using a switch statement switch v := value.(type) { case int, float: fmt.Println(“Number”) case *int: fmt.Println(“Int Pointer”) case string: fmt.Println(“String”) default: fmt.Println(“Other”) } Go - Nathan Reale
Break and Continue • Both work that same as in C • A break statement can also have a label attached, and it will jump to that label • Like goto Go - Nathan Reale
Functions • Functions begin with “func”, then name, parameters, and return values func sum(s []int) int { • Functions can return multiple values • All parameters are passed by value, but pointers can be used to prevent passing large types, or modify the parameters • Functions can have named return values that can be used within the function • They are initialized to the 0 values • They are returned with an empty return statement Go - Nathan Reale
Functions func sum(s []int) (sum int, ok bool) { if len(s) == 0 { return // returns 0 and false } for _, value := range s { sum += value } return sum, true } // total, ok := sum(values) Go - Nathan Reale
Defer • The defer keyword can be used to postpone executing a function until the current function returns • Used commonly to close files and unlock a mutex func readFile() { File.open() defer File.close() // More Code } Go - Nathan Reale
Function Literals • Anonymous functions can be declared and assigned to a variable - These functions are closures and first class values func eval(f func(int)int, param int) int { return f(param) } eval(func(i int)int { return i*i }, 5) Go - Nathan Reale
Methods on Structs • Instead of classes, Go uses methods with a specific type as the reciever • For example, the date struct used earlier could have a method attached to it to format the date for output func (d *Date) String() string { return fmt.Sprintf(“%s %d, %d”, d.month, d.day, d.year) } // fmt.Println(d.String()) Go - Nathan Reale
Methods on Structs • The method can be on either a pointer to the type or the type itself, and will be called the same • Using a pointer sends a reference to the function, while using the type itself sends a copy • Methods can also be on primitive types like int • The print functions in fmt can print a type automatically if it overrides the “String” method Go - Nathan Reale
Methods on Structs • If a struct has an anonymous field of a certain type, it inherits the methods for that type // Using the event type from before pi := &Event{ “Pi Day”, {“March”, 14, 2010}} fmt.Println(pi.String()) Go - Nathan Reale