- What are different data types in go
- what is a package in go
- what is go workspace
- what is GOPATH
- what are different directories inside a go project
- What are different data structures in go
- How to iterate maps in go
- How do you create go modules
- Explain go modules
- Function syntax in go
- Method syntax in go
- How do you declare inline function
- What is the use of empty interface
- How access modifiers work in go
- what is GOPATH and GOROOT
- Explain polymorphism in go
- Explain different print formats
- What is defautl value of a global, local, & pointer variable
- Does go support method overloading, operator overloading, type inheritance
- Write a program on pointers
- How do you copy slices
- How do you copy interfaces and structs
- How do you compare two structs maps and slices
- How do you compare two interfaces
- Explain go get command
- How do you do indentation
- Explain closures in go
- How to increase slice capacity
- How to convert string to int
- What is & and * in go
- Explain ++ and -- in golang
- Does go support indexing
- How to convert string to byte array & viceversa
- int8(aka byte)
- int16
- int32(aka rune, pronounced as roon (as room))
- int64
- float64
- byte
- bool
- string
a package is a directory where all go files resides.
a workspace is a directory heirarchy with two root directories,
- src -> go source files (typically contains multiple vcs based directories example, github.com)
- bin -> executable files
- pkg -> shared libs used by executables, example: go mod dependencies
It specifies the go workspace
- cmd -> will have sub-directories for cli based
- pkg -> if you need your code to be re-used by other projects (careful with this)
- internal -> if you want your code to be private
- api -> openapi/swagger
- web -> web components
- configs -> configurations
- init -> system init/process manager (systemd, sysv etc..)
- scripts -> build/installs
- build -> for deb,rpm,ami,docker images etc..
- deployments -> docker-compose, k8s yaml, terraform etc.
- test -> testing
- Array: fixed length
- Slice: variable length
- Maps: key values
- Struct: is a collection of fields of same/diff types
using range keyword
m := map[string]string{ "key1":"val1", "key2":"val2" };
for k, v := range m {
fmt.Printf("key[%s] value[%s]\n", k, v)
}using init command
go module initGo module is a dependency management system introduced from go v1.11
a module is a collection of go packages stored in go.mod file
func add(x int32, y int32) return int32 {
return x+y
}type Cal struct {
x int32
y int32
}
func (*Cal) add(x int32, y int32) int32 {
return x + y
}
func main() {
c := &Cal{}
c.add(2, 2)
fmt.Println(c.add(2, 2))
}inline function is an anonymous function used
func(){
fmt.Println("Hello")
}()value := func(){
fmt.Println("Hello")
}
value()Interface has two meanings
- interface is a set of method declaration
- emtpy interface is a type used to dynamic type conversion
-
Example, You can pass int or float, its dynamic
func add (x interface{}, y interface{}) { x+y }
-
there are two types of access modifiers
- exported (Accessible outside package)
- unexported (Accessible only within the package)
USING UPPERCASE WILL EXPORT A METHOD OR VARIABLE TO OUTSIDE PACKAGE
Foo int; // exported - accessible outside package
bar int; // unexported - only accessible witGOPATH specifies go workspace and GOROOT specifies go installation directory
Polymorphism can be achieved using interface
type User struct {
username string
email string
}
type UserI interface {
getEmail() string
}
func (u *User) getEmail() string {
return u.username
}
func main(){
var userI UserI
userI = &User{"zillani", "shaikzillani@gmail.com"}
fmt.Println(userI.getEmail())
}Printf -> formats and prints
Sprintf -> formats and doesn't prints, needs to be assigned
%d -> digit
%s -> string
%T -> type
%v -> default format global -> 0
local -> 0
pointer -> nilmethod overloading -> no
operator overloading -> -
type inheritance -> -Swapping two variables
package main
import "fmt"
func swap(px, py *int){
temp := *px
*px = *py
*py = temp
}
func main(){
a:=1
b:=2
fmt.Println("Before swapping: ",a,b)
swap(&a,&b)
fmt.Println("After swapping: ",a,b)
}using MAKE or using array declaration
s:= make([]int,3)
s[0] = 1
s[1] = 2
s[2] = 3
s2 := []int{1,2,3}
fmt.Println(s,s2)s1 := []int{1, 2, 3}
s2 := make([]int, 3)
copy(s2, s1)
fmt.Println(s1)
fmt.Println(s2)To copy maps you need to iterate values over the map
m1 := make(map[int]string)
m1[1] = "a"
m1[2] = "b"
m2 := make(map[int]string)
for key, value := range m1 {
m2[key] = value
}
fmt.Print(m2)copying interface means copy the underlying struct, & structs copied using assignment operator
type Point struct {
x int
y int
}
func main() {
p1 := Point {2,2}
p2 := p1
fmt.Println(p1)
fmt.Println(p2)
}using reflect api,
type Point struct {
x int
y int
}
func main() {
m1 := map[string]int{
"a": 1,
"b": 2,
}
m2 := map[string]int{
"a": 1,
"b": 2,
}
s1 := []byte{'a', 'b', 'c'}
s2 := []byte{'c', 'd', 'e'}
p1 := Point {2,2}
p2 := Point {3,3}
fmt.Println(reflect.DeepEqual(m1, m2))
fmt.Println(reflect.DeepEqual(s1, s2))
fmt.Println(reflect.DeepEqual(p1, p2))Using assignment operator
var z interface{} = 2
var y interface{} = 2
fmt.Println(z == y)go get is used for installations, suppose if you are installing golint, you do,
go get -u golang.org/x/lint/golintthe source code of golint will be downloaded and copied to $GOPATH/src/golang.org/x/lint
and the binary golint will be copied to $GOPATH/bin
since this is added to PATH, during installation, the binary will be
available to the system
using go fmt,
example,
go fmt hello.gogo fmt by default uses tabs & spaces are not longer used/recommended.
var global func()
func closure() {
var A int = 1
func() {
var B int = 2
func() {
var C int = 3
global = func() {
fmt.Println(A, B, C)
fmt.Println(D, E, F) // causes compilation error
}
var D int = 4
}()
var E int = 5
}()
var F int = 6
}
func main() {
closure()
global()
}global function has access to,
- It has access to A,B,C since the layer of enclosure does not matter
- It doesn’t have access to D,E,F since their declaration don’t precede
- Even after execution of “closure” function, it’s local variables were not destroyed. They were accessible in the call to “global” function
s = s[:cap(s)]import (
"fmt"
"strconv"
)
s := "123"
num,_ := strconv.Atoi(s)
fmt.Println(num)& gives address of a variable
\* used to hold the address of a variable
func main(){
var x int = 2;
var y *int = &x
fmt.Println("Address of x ",y)
}++ and -- are statements but not expressions check here
b := []byte("ABC€")
fmt.Println(b) // [65 66 67 226 130 172]s := string([]byte{65, 66, 67, 226, 130, 172})
fmt.Println(s)
