Go is a compiled language, and like many languages, it makes heavy use of the command line. Go is both the name of the programming language and the name for the toolset used to build and interact with Go programs.
Go is a statically typed programming language. What that means is the compiler always wants to know what the type is for every value in the program. When the compiler knows the type information ahead of time, it can help to make sure that the program is working with values in a safe way. This helps to reduce potential memory corruption and bugs, and provides the compiler the opportunity to produce more perform-ant code.
Go struct lets you create your own types by combining one or more types, including both built-in and user-defined types. Structs are the only way to create concrete user-defined types in Go. When you create your own types using struct, it is important to understand that Go does not provide support for inheritance in its type system, but it favors composition of types that lets you create larger types by combining smaller types.
Its concurrency mechanisms make it easy to write programs that get the most out of multi core and networked machines, while its novel type system enables flexible and modular program construction. When a function is created as a goroutine, it's treated as an independent unit of work that gets scheduled and then executed on an available logical processor.
Statically typed programming languages do type checking (i.e. the process of verifying and enforcing the constraints of types) at compile-time as opposed to run-time. Dynamically typed programming languages do type checking at run-time as opposed to compile-time
Go is a statically typed programming language. This means that variables always have a specific type and that type cannot change. The keyword var is used for declaring variables of a particular data type
Reference links
http://www.golangprograms.com/go-language.html
http://golangtutorials.blogspot.com/2011/05/very-simple-go-hello-world-line-by-line.html
https://gobyexample.com/hello-world
Practice Online
https://play.golang.org
Data Types:
int,float,string,error
Basics of GO lang
-------------Hello Wolrd program------------
//comments
//Start the program with
package main //No "quotes"
import "fmt" //this will import "fmt" from package main, note " quotes"
//OR
//for multiple imports
import (
"fmt"
"time"
)
func main(){
//To print something, Notice capital P
fmt.Println("Your text")
//You can add multiple string or do a small calculation inside print statement
fmt.Println("My " + "Calculation is : 2+2 = ", 2+2 )
var x int=2
fmt.Printf("The no is %d",x ) // NOTE Printf, not Println
}
-------Variable Declaration and Initialization-------
If variable is defined but not initialized, it will return zero (for int)
var a, b string // Declaring a and b variable of type string
a, b = "Mystring", "1" //Initializing the above variables
//OR
var a, b string = "Mystring", "1" // Declaring a and b variable of type string and Initializing
//OR
a, b := "Mystring", "1" // Shorthand for declaring a and b variable and Initializing >> NO type string Needed
fmt.Println(a,b)
----------------Loops---------------
for is Go’s only looping construct.
for i:=0;i<3;i++{ // NO (braces) in for loop
fmt.Println(i)
}
//OR
i :=0
for i<3{
fmt.Println(i)
i++
}
-----------Continue and Break Statement-------------
for i:=0;i<3;i++{ // NO (braces) in for loop
if i ==2{
fmt.Println(i)
break //Break the loop
continue // Skip the current iteration and continue to the next iteration >> NOT WORKING
} else {
fmt.Println("in else")
}
}
-------------If/Else statement--------------
You can have an if statement without an else. There is NO elif,
if num := 9; num < 0 { //A statement can precede conditionals; any variables declared in this statement are available in all branches.
fmt.Println(num, "is negative")
} else if num < 10 { //accessing this variable in branches; "else if" rather elif
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
fmt.Println(num, "is negative") //undefined: num as this is outside the if statement
-----------------Array------------------
In Go, an array is a numbered sequence of elements of a specific length.
package main
import "fmt"
func main(){
An array literal can be specified like so:
b := [2]string{"Penn", "Teller"}
Or, you can have the compiler count the array elements for you:
b := [...]string{"Penn", "Teller"}
In both cases, the type of b is [2]string. source - https://go.dev/blog/slices-intro
var a [5]int //Declare an array of integer having length 5, Default integer value is ZERO: Note the data type is [5]int
fmt.Println(a)
a =[5]int{1,2,3,4,5} //initialize the array
fmt.Println(a)
fmt.Println("length of array :", len(a))
a = [5]int{6,7,8} // Partially initialize the array, remaining will be ZERO
fmt.Println(a)
a[4] = 100 //at specific index
fmt.Println(a)
b :=[5]int{1,2,3,4,5} //Declare and initialize
fmt.Println("b is :",b)
var twoD [2][3]int //Declare two Dimension array
fmt.Println(twoD)
for i :=0; i<2;i++{
for j:=0; j<3;j++{
twoD[i][j] =i+j //Assign value
}
}
fmt.Println(twoD)
}
---------------Slice------------
More commonly used in GO and it does not have fixed length when declared.
Slices are a key data type in Go, giving a more powerful interface to sequences than arrays.
The type specification for a slice is []T, where T is the type of the elements of the slice. Unlike an array type, a slice type has no specified length.
s := make([]string, 3)
fmt.Println("emp:", s) // print [0,0,0] all empty
//The zero value of a slice is nil while an array is ZERO??
We can set and get just like with arrays.
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("set:", s)
s = append(s, 6, 7) //to append more elements ; CAN NOT append into an ARRAY as they are fixed size
fmt.Println(s)
EXAMPLE:
package main
import "fmt"
func main(){
slice :=[]int{1,2,3,4} //No need to define length
fmt.Println(slice)
//OR
slice1 :=make([]int,4) //Create a slice1 using make having integer, length 4
fmt.Println("slice1 is : ",slice1,len(slice1), cap(slice1))
slice[0] =5
slice[1] =6
fmt.Println(slice)
//slice1[0] =5
//fmt.Println(slice1)
//OR
var slice2 []int //Declare a NIL slice, and the length and capacity of a NIL slice is ZERO
fmt.Println("NIL slice2 is : ", slice2, len(slice2), cap(slice2))
slice2 =[]int{1,2,3} //Assign value
fmt.Println("slice2 is : ", slice2, len(slice2), cap(slice2))
}
FACTs:
s :=[]int{1,2,3,4,5}
s =s[2:4] // this is NOT going to copy the data but pointing to the same slice from index 2 to end, So this work like a pointer
// this will return [3,4]
Slicing does not copy the slice’s data
func main(){
s :=[]int{1,2,3,4,5} //No need to define length
fmt.Println(s)
s =s[2:4] //Creating another slice,
fmt.Println("Sub slice is :",s, len(s), cap(s))
// length of this new slice is "2" but it can grow up to the end of original slice(s) so capacity is 3
// >>output [3,4] 2 3
}
source : https://go.dev/blog/slices-intro
NOTE: CHECK /TBD append for array
----------------Maps--------------
Maps are Go’s built-in associative data type (sometimes called hashes or dicts in other languages).
To create an empty map, use the builtin make: make(map[key-type]val-type).
Example:
m :=make(map[string]int)
package main
import "fmt"
func main(){
m :=make(map[string]int) // Define
m["k1"] =1 //initializing
m["k2"] =2 //initializing
//OR
n :=map[string]int{"l1":3, "l2":4} //define and initialize together
fmt.Println(n)
val1 :=n["l1"]
fmt.Println("value is :", val1)
fmt.Println(m)
fmt.Println("length of m is ", len(m))
fmt.Println("value for k1 is ",m["k1"])
delete (m,"k2")
fmt.Println("After deleting a k2 key, amp is ", m)
val2, iskeyExist :=m["k2"] //val2 will be ZERO if key does not exist, So the 2nd parameter is to check if key exist
fmt.Println("After deleting a k2 key, check if the key exist? val2 ",iskeyExist, val2)
}
---------------Range-------------
range on arrays and slices provides both the index and value for each entry
a :=[5]int{1,2,3,4,5}
package main
import "fmt"
func main(){
a:=[5]int{1,2,3,4,5}
for index,val :=range a { //range returns the index and value for arrays
fmt.Println(index,val)
}
m :=map[string]int{"k1":1,"k2":2} //range returns the key and value for maps
for key,val :=range m{
fmt.Println(key,val)
}
range on strings iterates over Unicode code points. The first value is the starting byte index of the rune and the second the rune itself.
for i, c := range "abc" {
fmt.Println(i, c)
// output will be
//0 97 index, hexadecimal value
//1 98
//2 99
}
}
---------------Functions------------
package main
import "fmt"
func plus(a int, b int, c string) (int, string){
return a+b, c
}
//OR
func plus(a, b int, c string) (int, string){ //combined similar datatype variable together
return a+b, c // returning multiple values
}
func main(){
fmt.Println(plus(2,3,"Adding"))
}
------------Variadic functions------------https://gobyexample.com/variadic-functions
Variadic functions can be called with any number of trailing arguments. For example, fmt.Println is a common variadic function.
package main
import "fmt"
func plus(nums ...int) int{ //number of argument is not fixed, 3 DOTS
total :=0
for _,num := range nums {
total +=num
}
return total
}
func main(){
fmt.Println(plus(2,3)) //calling the same function with any number of arguments
fmt.Println(plus(2,3,4))
fmt.Println(plus(2,3,4,5))
}
-------Closures---------
// Go supports [_anonymous functions_](http://en.wikipedia.org/wiki/Anonymous_function),
// which can form <a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"><em>closures</em></a>.
// Anonymous functions are useful when you want to define
// a function inline without having to name it.
package main
import "fmt"
// This function `intSeq` returns another function, which
// we define anonymously in the body of `intSeq`. The
// returned function _closes over_ the variable `i` to
// form a closure.
func intSeq() func() int {
i := 0
return func() int {
i++
return i
}
}
func main() {
// We call `intSeq`, assigning the result (a function)
// to `nextInt`. This function value captures its
// own `i` value, which will be updated each time
// we call `nextInt`. ????????????
nextInt := intSeq()
// See the effect of the closure by calling `nextInt`
// a few times.
fmt.Println(nextInt()) //OUTPUT 1
fmt.Println(nextInt()) //OUTPUT 2
fmt.Println(nextInt()) //OUTPUT 3
// To confirm that the state is unique to that
// particular function, create and test a new one.
newInts := intSeq()
fmt.Println(newInts()) //OUTPUT 1
}
//OUTPUT is
//1
//2
//3
//1
--------------Pointers-----------
package main
import "fmt"
func zeroval(ival int) {
ival = 0
//return ival
}
func zeroptr(ival *int){ //Data type is a Pointer to Integer
*ival = 1 //Initializing with pointer
}
func main(){
i :=2
//Passing by value
zeroval(i)
fmt.Println(i) //2
//Pass by reference
zeroptr(&i) //Calling by reference
fmt.Println(i) //1
}
----------Function returning pointer---------
func zeroptr(ival *int) *int{ //Return type is Pointer to Integer
*ival = 1
return ival // Returning a reference
}
func main(){
i :=2
//Pass by reference
fmt.Println(*zeroptr(&i)) //As return type is Pointer to Integer
}
--------Functiona returning errors----------in GO "error" is a data type
package main
import (
"fmt"
"errors" // Need to import "errors"
)
func square(num int) (int, error){ //return type should have "error"
if num < 0 {
err := errors.New ("Its a negative number") //define a new variable and use errors.New() method to pass the message
return -1, err //returning value as -1 and error message
}
return num**2, nil //here error is nil
}
OR
you can use err := fmt.Errorf("here is your error") for error type
-----------Struct----------------
package main
import "fmt"
type person struct{
name string
age int
}
func newperson(newpersonname string) *person{
newp :=person{name:newpersonname}
fmt.Println(newp)
return &newp
}
func main(){
p := person{"ABC",10}
fmt.Println("Hello", &p , p)
p.name = "XYZ"
fmt.Println("Hello", &p , p)
newperson("abcd")
fmt.Println("Hello new person", *newperson("abcd"))
}
NOTE : Memory address for struct not visible
The fmt package uses reflection to print out values, and there is a specific case to print a pointer to a struct as &{Field Value}.
If you want to see the memory address, use the pointer formatting verb %p.
fmt.Printf("&stud is: %p", &person)
func main(){
fmt.Printf("%p %v %v",newemployee("xyz"),newemployee("xyz"), *newemployee("xyz")) // Printing memory address, &{struct} and struct value
}
---------------Method--------------
Methods are similar to the functions defined inside a class (in c++), as GO is not OOP and it does NOT have class. We define the function outside the struct using a struct type receiver and call them as method. Methods can be defined for either pointer or value receiver types.
func (t ReceiverType) FunctionName(Parameters...) ReturnTypes...
Ex.
type Triangle struct { // Struct defined
a, b, c float64
}
func (t *Triangle) square() (float64, error) { //method defined by using the receiver Type
}
func main(){
t1 :=Triangle{} //Define the instance
t1.square() // Calling method/function using the instance
}
While the function are
func FunctionName(Parameters...) ReturnTypes...
-------Example of methods------
package main
import (
"fmt"
"errors" //import "errors"
)
type rect struct {
height, width float64
}
func (r *rect) area() (float64,error){ // Receiver type Pointer
if r.height <0 || r.width < 0 {
err := errors.New("Triangle is not valid")
return -1, err
}
return r.height*r.width, nil
}
Methods can be defined for either pointer or value receiver types. Here’s an example of a value receiver.
func (r rect) peri() (float64, error){ //receiver type value
if r.height <0 || r.width < 0 {
err := errors.New("Triangle is not valid")
return -1, err
}
return (r.height+r.width)*2, nil
}
func main(){
fmt.Println("Hello")
r :=rect{3.0, 2.0}
fmt.Println(r.area())
fmt.Println(r.peri())
}
--------What means TYPE when defining struct----------
type person struct{
name string
age int
}
The type keyword is there to create a new type. This is called type definition. The new type (in your case, Vertex) will have the same structure as the underlying type (the struct with X and Y). That line is basically saying "create a type called Vertex based on a struct of X int and Y int".
------------Interfaces-------------
Interfaces are named collections of method signatures.
Refer: https://gobyexample.com/interfaces