Types?

Go is statically typed language means every variable's type is fixed at compile time, which helps catch errors early and makes code reliable.

Types of types

Type Description
1. Basic Type int, float64, bool, string

var a int = 42
str := "Go is awesome" // Type inference
b := true
var f float64 = float64(a)      //Type Conversion
                
2. Aggregate Types 1. Arrays:An array is a fixed-size sequence of elements of the same type.

colors := [3]string{"red", "green", "blue"}
            

2. struct

type Person struct {
    Name string
    Age  int
}
func (p Person) fun() string {  //Define function for struct
    return "Hello, my name is " + p.Name
}
                
Reference Types Pointers: variable that stores the memory address of another variable (&)
slices:
maps
functions
channels

4. Interface

Interface only declares the functions those should be implemented by concrete types
This is similar to Abstract Class C++98, Concepts in C++20
In C++, we design our class hierarchy first. In Go, you often design your interfaces. These are Binded at Dynamic(ie runtime).
In Go, the philosophy is to "accept interfaces, return structs."

// Interface declares functions to be implemented by concrete types
type Speaker interface {
    Speak() string
}

// Concrete Struct A
type Human struct{}
func (h Human) Speak() string { return "Hello!" }

// Concrete Struct B
type Dog struct{}
func (d Dog) Speak() string { return "Woof!" }

// This function doesn't care if it gets a Human or a Dog
// accept interfaces, return structs
func MakeItTalk(s Speaker) {
    fmt.Println(s.Speak())
}
            

Interface Pollution Problem

Creating interfaces where they aren't actually needed. ie creating interface for every class
Symptoms of Interface Pollution
1. One-to-One Mapping: Every single struct has a corresponding interface
2.Harder Navigation: In an IDE, clicking "Go to Definition" on a method takes you to the interface definition rather than the actual code doing the work.
Polluted Interface Good Interface

// Defined in the same package as the logic, 
// just for the sake of it.
type Worker interface {
    DoWork()
}

type MyWorker struct{}
func (m MyWorker) DoWork() { ... }
          

// Defined by the CONSUMER who needs the work done.
type Performer interface {
    DoWork()
}

func Execute(p Performer) {
    p.DoWork()
}