Type / Data Type

Go is statically typed language that means every variable's data type is fixed at compile time.

Data types in Go

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 declares the functions those should be implemented by concrete types. Similar to Abstract Class C++98, Concepts in C++20.
C++: A class must explicitly inherit from the abstract class (class Dog : public Animal)
Go follows duck typing(If it walks like a duck and quacks like a duck, it's a duck), It means if type in Go implements all methods of interface, it automatically implements the interface(no need to provide implements or extends keyword)

package main

import "fmt"
// 1. Declare Abstract class (The Contract)
type Speaker interface {
	Speak() string
}

// 2. Declare a concrete classes
type Dog struct{ name string }
type Cat struct{ breed string }

// 3. Implement interface(Speaker not mentioned, it figured implicitly)
// (d Dog) is METHOD RECIEVER, telling this function is associated with a concrete Type=DOG
// if we remove method receiver, then this function cannot be associated with Type
func (d Dog) Speak() string {
	return "Bark " + d.name
}
func main() {
	var s Speaker          // Interface var
	s = Dog{"Tommy"}       // Valid! Dog implements Speak()
	fmt.Println(s.Speak())
}

Method Receiver

func (d Dog) Foo(v int) (int, error)
This function takes 1 argument=v, returns int, error
d is called method reciever and it associates function with type.
if there is no method reciever, then function cannot be associated with the type
Method Receiver is added before function name while function parameters are added after function name

Restrictions on Go Interfaces

1. Interface can have Methods only, variables, constants, or data fields should not be present
2. Cannot write the body ({ ... }) of a function inside an interface.
3. Implementing type must match the method name, parameters, and return types exactly

Use case of interface

Use Case Explanation
Multiple Structs, One Interface ie (Polymorphism) Allowing different structs to be treated as the same type because they all implement the same functions.
Eg: A database interface. You might have a MySQL struct and a MongoDB struct. Both implement a Save() function.

type Saver interface {
    Save(data string) error
}

func DataProcessor(s Saver) { // Any database can be passed into this function
    s.Save("important info")
}
            
Decoupling and Testing (Mocking)

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()
}