Golang Flashcards
Basic Types
bool string int (8, 16, 32, 64) uint (8, 16, 32, 64), uintptr - pointer byte (uint8) rune (uint32) like a char float (32, 64) complex (64, 128)
Other Types
Array Slice Struct Pointer Function Interface Map Channel
Variable Declaration
var foo string
foo = “Hello World”
var bar = “Hello World” => same as above interprets the type automatically
baz := “Hello World” => no need to type in var
Pointers
ptr -> var
string pointer cannot point to int pointer
pointer holds memory address
if we pass a pointer to a function then if the value changes outside of function then it also effects the value inside of the function.
message := “Hello World….”
var greeting *string = &message
Note: *string is required to store pointer value
&message => gets back address of message - this has to be stored inside a string pointer
- now greeting is a string pointer which points to message
- greeting store location of string message
fmt.Println(greeting, *greeting)
output => 0x123423, Hello World….
User Defined Types
type Customer struct {
name string
age int
}
func main(){ c1 = Customer{} c1.name = "Foo" c1.age = 10
c2 = Customer {name: “Bar”, age: 20}
c3 = Customer {“Bar”, 20}
}
Notes:
- no getters and setters
- no access specifiers
Constants
const { PI = 3.14 => float const Language = "Go" => string const }
const { A = iota B = iota C = iota }
fmt.Println(A, B, C)
0, 1, 2
const { A = iota B C }
fmt.Println(A, B, C)
0, 1, 2
- don’t have to initialize, it defaults to previous initialization
Functions
func Greet (s Salutation){ fmt.Println(CreateMessage(s.name, s.age)) }
func CreateMessage(name string, age int) string { return "hello " + name + ", your age is " + age }
Functions with multiple return types
func Greet (s Salutation){ m1, m2 = CreateMessage(s.name, s.age) fmt.Println(m1, m2) }
func CreateMessage (s Salutation) (string, string){ return "foo", "bar" }
===
s = Salutation {“foo”, 10}
Greet(s)
output
foo, bar
if you do not use a variable its an ERROR, so just use _ if you do not want a variable
i.e. _, m2 = CreateMessage(s.name, s.age)
Functions with names multiple return types
func CreateMessage(s Salutation) (message string, alternate string){ message = "foo" alternate = "bar" return }
Variadic Functions
- functions with variable input
func foo(name string, options ...string){ fmt.Println(name, options[0], options[1]) }
foo(“hello world”, “foo”, “bar”)
Function Types
- passing functions to other functions
func foo (name string, myfun string(int) (string)){ "Hello " + name + ", drinking age? " + myfun(10) }
func DrinkingEligible (age int) (string){ if (age > 18){ return "Yes" } else{ return "No" } }
==
foo(“hello “, DrinkingEligible)
Func Type 2
type DrikingEligibilityCalculator string(int) (string)
func foo (name string, cal DrinkingEligibilityCalculator){ "Hello " + name + ", drinking age? " + cal(10) }
func DrinkingEligibilityUS (age int) (string){ if (age > 21){ return "Yes" } else{ return "No" } }
func DrinkingEligibilityUK (age int) (string){ if (age > 18){ return "Yes" } else{ return "No" } } == foo("hello ", DrinkingEligibleUS) foo("hello ", DrinkingEligibleUK)
If statements
if age := 100 alive { print("still alive at ", age) } else{ print("not alive at ", age) }
age is defined in scope of the if statement.
Switch statement
switch name{ case "bob": print("Hello Bob") case "sally": print("hello sally") default: print("No name") }
no switching param needed, it will switch on bool
switch { case name == "bob": print("Hello Bob") case name == "sally": print("hello sally") default: print("No name") }
Loops
only have one type of loop i.e. FOR
for i := 0; i < 10; i++{
}
// similar to while loop i := 0 for i < 10 { i ++ }
for {
break;
}
Ranges
slice := [] foo {
“one”, “two”, “three”
}
for index, val := range slice {
print (“index: “ + index + “, value: “ + val)
}
Maps
- dictionary
var foo map [string] string {}
foo = make(map [string] string)
initialization #1
foo[“bar”] = “aaaa”
foo[“baz”] = “bbbb”
initialization #2 var foo map [string] string { "bar": "aaaa", "baz": "bbbb" }
to get values
foo[“bar”]
Operations == insert update => foo["baz"] = "kkkkk" delete => delete(foo, "baz")
Slices
long version
- its a subset of an array
- arrays are fixed lengths and are difficult to pass into functions
- slices are varying length and are easy to pass to functions
var foo [] int
foo = make([] int, 5, 10) => make a a slice of integers with initial length of 5 and capacity of 10
foo := [] int {1, 2, 3}
bar := [] baz {
{id: 1, name: “”}, {id: 2, name: “”}
}
slice of baz struct
slicing operations == foo[1:2] => 2 foo[0:2] => 1, 2 foo[0:] => 1, 2, 3
append(foo, 100)
append(foo, foo…) => append two slices
Methods on Struct
functions v/s methods (operate on structs)
type Customer struct {
Id string
Name string
}
type Customers [] Customer
func (customers Customers) SayHello(){ for _, c := range customers { print(c.Id, c.Name) } }
usage == goodCustomers := Customers { {1, "Alice"}, {2, "Bob"}, {3, "Cathy"} }
goodCustomers.SayHello()
Methods
type Customer struct {
Id string
Name string
}
func (customer *Customer) rename (newName sting){ customer.name = newName }
here we have a pointer to the object, so it will change the underlying struct
john = Customer {1, “John”}
john.rename(“bob”)
Concurrency
o/p
- go routines
func sayHello(arg){ print("Hello world...") }
go sayHello(“Concurrent”) ====> runs on its own thread
sayHello(“Normal”)
time.Sleep(100 * time.Millisecond)
Hello World Normal
Hello World Concurrent