You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Go has a clean and concise syntax that is easy to understand, even for beginners.
The language design emphasizes simplicity and readability, reducing the cognitive load for developers.
2. Performance
Go is a statically typed, compiled language that offers performance close to that of lower-level languages like C and C++.
It produces fast and efficient executables, which makes it suitable for high-performance applications.
3. Concurrency
Go's concurrency model is one of its standout features. Goroutines and channels provide an efficient way to handle concurrent tasks.
This makes Go particularly well-suited for building scalable and high-concurrency applications, such as web servers and networked services.
4. Standard Library
Go's standard library is robust and extensive, covering a wide range of functionalities needed for backend development, including HTTP servers, file I/O, and cryptography.
The standard library is well-documented and designed to be easy to use.
5. Strong Community and Ecosystem
Go has a growing and active community that contributes to a rich ecosystem of libraries and tools.
There are many frameworks and libraries available for web development, database interaction, testing, and more.
6. Cross-Platform Compatibility
Go supports cross-compilation, allowing you to build binaries for multiple platforms from a single codebase.
This makes deployment across different environments straightforward.
7. Built-in Tooling
Go comes with built-in tools for testing (go test), formatting (go fmt), and dependency management (go mod).
These tools promote good coding practices and help maintain code quality.
What Makes Go Different from Other Languages?
1. Concurrency Model:
Go's goroutines and channels offer a simpler and more efficient way to handle concurrency compared to traditional threading models in languages like Java or Python.
2. Compilation Speed:
Go compiles quickly, which speeds up the development cycle and allows for rapid iterations.
3. Simplicity in Design:
Go was designed to avoid complexity. It lacks many features found in other languages (like inheritance, generics, and assertions), which can be seen as a feature that reduces potential bugs and makes the language easier to learn and use.
4. Garbage Collection:
Go includes garbage collection, which simplifies memory management compared to languages like C or C++.
What is Concurrency?
Explanation:
Concurrency means executing multiple tasks simultaneously, but not necessarily at the same instant. It's about dealing with many things at once and making progress on several tasks concurrently.
Example 1: Simple Concurrency with Goroutines
In Go, concurrency is achieved using goroutines, which are lightweight threads managed by the Go runtime.
package main
import (
"fmt""time"
)
funcprintNumbers() {
fori:=1; i<=5; i++ {
fmt.Println(i)
time.Sleep(1*time.Second) // Simulate a time-consuming task
}
}
funcmain() {
goprintNumbers() // Start a new goroutinefmt.Println("Goroutine started")
time.Sleep(6*time.Second) // Give the goroutine time to finish
}
Example 2: Synchronizing Goroutines with Channels
Channels provide a way for goroutines to communicate and synchronize their execution.
package main
import (
"fmt"
)
funcsum(a, bint, resultchanint) {
result<-a+b// Send the result to the channel
}
funcmain() {
result:=make(chanint)
gosum(1, 2, result)
fmt.Println("Sum:", <-result) // Receive the result from the channel
}
In the examples:
Goroutines: The go keyword starts a new goroutine.
Channels: Channels are used to communicate between goroutines.
Key Concepts of Concurrency in Go
1. Goroutines:
Lightweight threads managed by the Go runtime.
Syntax: go functionName()
2. Channels:
Used for communication between goroutines.
Syntax: ch := make(chan int)
Example with Multiple Goroutines and Channels
package main
import (
"fmt"
)
funcworker(idint, jobs<-chanint, resultschan<-int) {
forj:=rangejobs {
fmt.Printf("Worker %d started job %d\n", id, j)
results<-j*2// Simulate work by multiplying the job numberfmt.Printf("Worker %d finished job %d\n", id, j)
}
}
funcmain() {
jobs:=make(chanint, 100)
results:=make(chanint, 100)
// Start 3 worker goroutinesforw:=1; w<=3; w++ {
goworker(w, jobs, results)
}
// Send 5 jobs and close the channelforj:=1; j<=5; j++ {
jobs<-j
}
close(jobs)
// Collect results from workersfora:=1; a<=5; a++ {
fmt.Println("Result:", <-results)
}
}
In the examples:
Worker Function: Each worker receives jobs from the jobs channel and sends results to the results channel.
Main Function: Starts worker goroutines, sends jobs to the jobs channel, and collects results from the results channel.
What is go mod?
go mod is a tool introduced in Go 1.11 to manage dependencies in Go projects. It helps you keep track of the libraries and packages your project depends on, ensuring consistent builds by specifying exact versions of these dependencies.
1. Module Initialization:
Initializes a new module in the current directory, creating a go.mod file.
Command: go mod init
gomodinitexample.com/myproject
2. Add a dependency:
Automatically downloads and installs the dependencies specified in your go.mod file.
-Command: go mod tidy, go get
gogetgithub.com/gin-gonic/gin
Note: We can compare go mod with node.js package.json
Comparing go mod with Node.js's package.json
Feature
go mod
package.json
Initialization
go mod init
npm init
Dependency File
go.mod
package.json
Adding Dependencies
go get
npm install
Module Caching
$GOPATH/pkg/mod
node_modules
Command to Install
Implicit with go build
npm install
go mod is similar to package.json in that both are used to manage dependencies in their respective ecosystems (Go and Node.js).
go mod provides a file (go.mod) to list dependencies and their versions, similar to how package.json does for Node.js.
Both tools help ensure consistent builds by keeping track of exact dependency versions and provide commands to add, update, and manage dependencies
Variables:
In Go, there are two ways to declare a variable
1. Use the var keyword, followed by variable name and type
2. Use the := sign, followed by the variable value
package main
import ("fmt")
funcmain() {
varOne:=100varTwo:=2fmt.Println(varOne)
fmt.Println(varTwo)
}
2. Use the const keyword, followed by variable name and type
When we use the const keyword can not change the value of the variable. It is meant to be constant
package main
import ("fmt")
funcmain() {
constcountryName="India"constage=18fmt.Println(countryName)
fmt.Println(age)
}
Assigning Types + Type Inferred
package main
import ("fmt")
funcmain() {
varfruitstring="Mango"// type is stringvaruser="Jaddu"// type is inferrednumber:=2// type is inferredfmt.Println(fruit)
fmt.Println(user)
fmt.Println(number)
}
package main
import ("fmt")
funcmain() {
var (
numintnumberint=1greetingsstring="hello"
)
fmt.Println(num)
fmt.Println(number)
fmt.Println(greetings)
}
Go Variable Naming Rules:
1. A variable name must start with a letter or an underscore character (_)
2. A variable name cannot start with a digit
3. A variable name can only contain alpha-numeric characters and underscores (a-z, A-Z, 0-9, and _ )
4. Variable names are case-sensitive (age, Age and AGE are three different variables)
5. There is no limit on the length of the variable name
6. A variable name cannot contain spaces
7. The variable name cannot be any Go keywords I need this kind of explanation along with code example to learn go in readme syntax for each topic in go
Explanation:
var: Keyword used to declare a variable.
name: Variable name (follows naming conventions).
string: Data type stored in the variable (name).
=: Assignment operator, assigns the value "John Doe" to name.
User Inputs in Go:
In Go, you can take user input using the fmt package. The Scan functions allow you to read input from standard input (stdin).
package main
import"fmt"funcmain() {
varnamestringfmt.Print("Enter your name: ")
// Scanln reads a line from stdin// you can use Scan also to readfmt.Scanln(&name)
fmt.Println("Hello,", name)
}
Example: Reading Multiple Inputs
package main
import"fmt"funcmain() {
varageintvarnamestringfmt.Print("Enter your name: ")
fmt.Scanln(&name)
fmt.Print("Enter your age: ")
fmt.Scanln(&age)
fmt.Printf("Hello, %s! You are %d years old.\n", name, age)
}
Pointers in Go:
A pointer is a variable that points to the memory address of another variable.
Pointers in Go allow you to store and manipulate the memory addresses of variables. This can be useful for several reasons, such as passing large structures efficiently, modifying the value of a variable inside a function, or working with data that needs to be shared across different parts of a program.
In Go, the * symbol is used to declare a pointer. A pointer is a variable that holds the memory address of another variable. Pointers are useful because they allow functions to modify the value of a variable directly, rather than working with a copy of the variable.
Basic Concepts
1. Pointer Declaration: A pointer holds the memory address of a variable.
2. Address Operator (&): Used to get the memory address of a variable.
3. Dereference Operator (*): Used to access the value stored at the memory address.
Example: Basic Pointer Usage
1. Declare a Pointer: Use * to declare a pointer type.
2. Get Address: Use & to get the address of a variable.
3. Dereference: Use * to access the value at the pointer's address.
package main
import"fmt"funcmain() {
// Declare a variablevaraint=42// Declare a pointer that holds the address of variable avarp*int=&a// Print the value of afmt.Println("Value of a:", a)
// Print the address of afmt.Println("Address of a:", &a)
// Print the value of the pointer (which is the address of a)fmt.Println("Pointer p points to address:", p)
// Dereference the pointer to get the value stored at the addressfmt.Println("Value at the address p points to:", *p)
}
Arrays in Go:
An array in Go is a collection of elements of the same type that are stored in a contiguous block of memory. Arrays are of fixed size, meaning once you define the size of an array, it cannot be changed.
Declaration without Initialization
You can declare an array without initializing its elements. All elements will be set to the zero value for the type (e.g., 0 for integers, "" for strings).
Slices are a fundamental data structure in Go that provide a flexible and powerful way to work with collections of data. Unlike arrays, slices can grow and shrink in size (slices are dynamically sized), making them more versatile for most use cases.
Creating a Slice
1. From an Array
You can create a slice from an existing array by specifying a range.
package main
import"fmt"funcmain() {
arr:= [5]int{1, 2, 3, 4, 5}
slice:=arr[1:4] // Creates a slice from the second to the fourth elementfmt.Println(slice) // Output: [2 3 4]
}
2. Using the make Function
The make function allows you to create a slice with a specified length and capacity. The length is the number of elements in the slice, and the capacity is the number of elements in the underlying array starting from the first element in the slice.
Slices are references to an underlying array. This means that if you modify the elements of a slice, the changes will be reflected in the underlying array and any other slices that refer to the same array.
Slices in Go are more flexible and dynamic than arrays.
Creating Slices: From arrays, using make, and slice literals.
Slices Are References: Modifying one slice can affect others and the underlying array.
Appending: Use append to add elements.
Copying: Use copy to copy elements between slices.
Slicing: Create new slices from existing ones.
Iterating: Use for or for range loops.
Maps in Go:
Maps in Go are a built-in data structure that associates keys with values. They provide a way to store and retrieve data efficiently, similar to dictionaries in Python or Objects in Js.
A map is an unordered collection of key-value pairs. Each key in a map is unique, and you can use the key to look up the corresponding value.
Default value of a map is nil
Creating and Initializing Maps
Using Map Literals
You can create and initialize a map using a map literal.
package main
import"fmt"funcmain() {
// Create and initialize a map using a map literalm:=map[string]int{
"Jaddu": 24,
"Bob": 25,
}
fmt.Println(m) // Output: map[Alice:30 Bob:25]
}
Example:
package main
import"fmt"funcmain() {
// Declare and initialize a mapperson:=map[string]string{
"name": "John",
"email": "john@example.com",
}
// Access a value using a keyfmt.Println("Name:", person["name"])
// Add a new key-value pairperson["age"] ="30"// Update a valueperson["email"] ="john.doe@example.com"// Delete a key-value pairdelete(person, "age")
// Iterate over the mapforkey, value:=rangeperson {
fmt.Printf("%s: %s\n", key, value)
}
}
Using the make Function
You can create a map using the make function, specifying the key type and value type.
package main
import"fmt"funcmain() {
// Create a map with string keys and int valuesm:=make(map[string]int)
fmt.Println(m) // Output: map[]
}
Adding and Retrieving Values
Adding Values
You can add values to a map using the syntax map[key] = value.
Adding/Retrieving Values: Use map[key] = value and map[key].
Checking Existence: Use the second return value from a map lookup.
Deleting Keys: Use the delete function.
Iterating: Use for range loops.
Structs in Go:
Structs are one of the most important and commonly used data structures in Go. They allow you to group together related data, which can be of different types, into a single unit. You can think of a struct as a way to create your own custom data types.
A struct is a collection of fields. Each field has a name and a type. Structs are used to group related data together.
You can compare Struct with Schema in Mongoose
Defining a Struct
To define a struct, use the type and struct keywords.
package main
import"fmt"// Define a struct type named PersontypePersonstruct {
NamestringAgeintCitystring
}
funcmain() {
// Create a new instance of the Person structvarp1Personp1.Name="Jaddu"p1.Age=24p1.City="Bangalore"fmt.Println(p1)
// Output: {Jaddu 24 Bangalore}
}
Creating and Initializing Structs
Using Struct Literals
You can create and initialize a struct using a struct literal.
package main
import"fmt"// Define the Person structtypePersonstruct {
NamestringAgeintCitystring
}
funcmain() {
// Initialize a struct using a struct literalp2:=Person{Name: "Sara", Age: 22, City: "Los Angeles"}
fmt.Println(p2) // Output: {Sara 25 Los Angeles}
}
Using new Function
You can also create a pointer to a struct using the new function.
package main
import"fmt"// Define the Person structtypePersonstruct {
NamestringAgeintCitystring
}
funcmain() {
// Create a pointer to a new Person structp3:=new(Person)
p3.Name="Charlie"p3.Age=35p3.City="New York"fmt.Println(*p3) // Output: {Charlie 35 New York"}
}
Accessing and Modifying Struct Fields
You can access and modify the fields of a struct using the dot notation.
package main
import"fmt"// Define the Person structtypePersonstruct {
NamestringAgeintCitystring
}
funcmain() {
// Create and initialize a Person structp:=Person{Name: "Dave", Age: 40, City: "San Francisco"}
// Access fieldsfmt.Println("Name:", p.Name)
// Output: Name: Davefmt.Println("Age:", p.Age)
// Output: Age: 40fmt.Println("City:", p.City)
// Output: City: San Francisco// Modify fieldsp.Age=41fmt.Println("Updated Age:", p.Age)
// Output: Updated Age: 41
}
Nested Structs
Structs can be nested, meaning you can have a struct as a field within another struct.
package main
import"fmt"// Define the Address structtypeAddressstruct {
StreetstringCitystringZipstring
}
// Define the Person struct with an embedded Address structtypePersonstruct {
NamestringAgeintAddressAddress
}
funcmain() {
// Create and initialize a nested structp:=Person{
Name: "Eve",
Age: 28,
Address: Address{
Street: "123 Main St",
City: "Boston",
Zip: "02118",
},
}
fmt.Println(p)
// Output: {Eve 28 {123 Main St Boston 02118}}// Access nested fieldsfmt.Println("City:", p.Address.City)
// Output: City: Boston
}
Capitalization Rules
In Go, the visibility of struct fields and methods is determined by their capitalization. By following this convention, you control whether a field or method is accessible outside of the package where it is defined.
1.Exported (Public) Fields and Methods:
Fields and methods that start with an uppercase letter are exported, meaning they are accessible from other packages.
2.Unexported (Private) Fields and Methods:
Fields and methods that start with a lowercase letter are unexported, meaning they are only accessible within the package where they are defined.
package main
import (
"fmt"
)
typePersonstruct {
Namestring// Exported field (public)ageint// Unexported field (private)
}
// Exported methodfunc (pPerson) GetAge() int {
returnp.age
}
// Unexported methodfunc (p*Person) setAge(ageint) {
p.age=age
}
funcmain() {
p:=Person{Name: "Alice", age: 30}
// Accessing exported fieldfmt.Println("Name:", p.Name)
// Accessing unexported field directly (will cause a compilation error)// fmt.Println("Age:", p.age)// Accessing unexported field via exported methodfmt.Println("Age:", p.GetAge())
// Setting age using an unexported method within the same packagep.setAge(35)
fmt.Println("New Age:", p.GetAge())
}
Use uppercase for fields and methods that need to be accessed from outside the package.
Use lowercase for fields and methods that should be hidden within the package.
Methods on Structs
You can define methods on structs to add behavior to them. A method is a function with a special receiver argument.
package main
import"fmt"// Define the Person structtypePersonstruct {
NamestringAgeint
}
// Define a method on the Person structfunc (pPerson) Greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}
funcmain() {
// Create and initialize a Person structp:=Person{Name: "Jaddu", Age: 20}
// Call the Greet methodp.Greet()
// Output: Hello, my name is Jaddu and I am 20 years old.
}
Struct Tags:
Struct tags in Go are metadata attached to struct fields. They provide instructions to the Go runtime about how to handle the fields when encoding (marshaling) or decoding (unmarshaling) structs to/from different formats like JSON, XML, or database rows.
Example Struct with Tags
package main
import (
"encoding/json""fmt"
)
typeUserstruct {
IDint`json:"id"`Namestring`json:"name"`Emailstring`json:"email,omitempty"`Passwordstring`json:"-"`
}
Explanation of Struct Tags
1. Basic Syntax: Struct tags are written after the field type and enclosed in backticks json:"tag".
2. Key-Value Pairs: Struct tags consist of key-value pairs separated by colons :. Each key-value pair provides a specific instruction.
json:"id": This instructs the JSON encoder to use "id" as the key when marshaling this field into JSON. For example, {ID: 1} becomes {"id": 1} in JSON.
json:"name": Similarly, this specifies that "name" should be used as the key in JSON.
json:"email,omitempty": The omitempty option tells the JSON encoder to omit this field from the JSON output if it's empty (""). Useful for optional fields.
json:"-": The dash- indicates that this field should be ignored by the JSON encoder. It won't appear in the JSON output.
Why Use Struct Tags?
Serialization: Struct tags are crucial for encoding Go structs into different formats like JSON, XML, etc., and vice versa.
Flexibility: They allow fine-grained control over how struct fields are represented in different data formats, ensuring compatibility and efficiency.
Summary:
Structs: Collections of fields that group related data.
Defining Structs: Use the type and struct keywords.
Creating Structs: Use struct literals or the new function.
Accessing/Modifying Fields: Use the dot notation.
Nested Structs: Structs can contain other structs.
Methods on Structs: Define methods to add behavior to structs
Functions in Go:
In Go, a function is a block of code that can be executed multiple times from different parts of your program. It's a way to group a set of statements together to perform a specific task.
To define a function in Go, you use the func keyword, followed by the function name, parameters (if any), and the return type (if any).
Example of a function in Go:
package main
import"fmt"// Define a function named greet that takes a string parameter and returns a stringfuncgreet(namestring) {
fmt.Println("Hello, "+name+"!")
}
funcmain() {
// Call the greet function and print the resultgreet("John")
greet("Jane")
// Output: Hello, John!// Hello, Jane!
}
Function Declaration
A function declaration consists of the func keyword, followed by the function name, parameters in parentheses, and the function body in curly braces.
funcfunctionName(param1type1, param2type2, ...) returnType {
// function body
}
Function Parameters
Functions can take zero or more parameters, which are specified in the parentheses after the function name. Parameters are separated by commas.
funcadd(xint, yint) int {
returnx+y
}
In this example, the add function takes two int parameters, x and y.
Function Return Types
A function can return one or more values, which are specified after the parameter list. If a function returns no values, the return type is omitted.
In this example, the outer function returns a closure that has access to the x variable. The closure is called multiple times, and each time it increments the x variable and returns its value
Anonymous Functions
Functions in Go can be defined without a name and can be assigned to variables or passed as arguments.
package main
import"fmt"funcmain() {
// Define and call an anonymous functionfunc() {
fmt.Println("Hello, anonymous function!")
}()
// Define an anonymous function and assign it to a variableadd:=func(aint, bint) int {
returna+b
}
// Call the anonymous functionfmt.Println("Sum:", add(3, 4)) // Output: Sum: 7
}
Higher-Order Functions
A higher-order function is a function that takes another function as an argument or returns a function as a result.
In this example, the apply function takes a function f and an integer x as arguments. It calls the function f with the argument x and returns the result. The double function is passed as an argument to the apply function, which doubles the input value.
Panic Function in Go:
The panic function in Go is used to cause a program to terminate immediately and print an error message. It is generally used to handle unrecoverable errors that should stop the normal execution of the program. When panic is called, the program stops executing the current function, runs any deferred functions, and then terminates.
Example:
package main
import"fmt"funcmain() {
fmt.Println("Start of main function")
panic("Something went wrong!")
fmt.Println("This line will never be executed")
}
// O/P:Startofmainfunction
panic: Somethingwentwrong!goroutine1 [running]:
main.main()
/path/to/your/file.go:8+0x40exitstatus2
1. Usage
panic should be used for critical errors where the program cannot continue.
It is typically used in situations where something has gone seriously wrong, such as encountering an unexpected condition that makes further execution impossible or dangerous.
2. Behavior:
When panic is called, the program stops executing the current function and begins unwinding the stack.
Deferred functions (functions scheduled to run with defer) are executed in the reverse order they were deferred.
After running all deferred functions, the program exits and prints the panic message along with a stack trace to the console.
Example with defer
package main
import"fmt"funcmain() {
deferfmt.Println("This will be printed last, before the program exits")
fmt.Println("Start of main function")
panic("Something went wrong!")
fmt.Println("This line will never be executed")
}
Methods in Go:
In Go, methods are functions with a special receiver argument. The receiver can be a value or a pointer to a struct. Methods allow you to define behaviors associated with your data types.
Method Syntax:
func (receiverTypeReceiver) methodName(parameters) returnType {
// method body
}
Example:
package main
import (
"fmt"
)
// Defining the Person structtypePersonstruct {
FirstNamestringLastNamestringAgeint
}
// Method to get the full name of the personfunc (pPerson) FullName() string {
returnp.FirstName+" "+p.LastName
}
// Method to check if the person is an adultfunc (pPerson) IsAdult() bool {
returnp.Age>=18
}
// Method to increment the age of the person// Notice the pointer receiver to modify the original structfunc (p*Person) IncrementAge() {
p.Age++
}
funcmain() {
// Creating an instance of Personperson:=Person{
FirstName: "John",
LastName: "Doe",
Age: 20,
}
// Calling the FullName methodfmt.Println("Full Name:", person.FullName())
// Calling the IsAdult methodfmt.Println("Is Adult:", person.IsAdult())
// Incrementing the age using the IncrementAge methodperson.IncrementAge()
fmt.Println("New Age:", person.Age)
}
Real-Time Usage in API Development:
In a real-world scenario, you might define methods on structs that represent entities in your application. For example, in an API for user management, you might have a User struct with methods for various operations.
package main
import (
"encoding/json""fmt""net/http"
)
typeUserstruct {
IDint`json:"id"`Namestring`json:"name"`Emailstring`json:"email"`Passwordstring`json:"-"`
}
// Method to check if the email is valid (dummy example)func (uUser) IsValidEmail() bool {
// Simplified email validationreturnlen(u.Email) >5&&u.Email[len(u.Email)-4:] ==".com"
}
// Method to hide the password from JSON responsefunc (u*User) HidePassword() {
u.Password=""
}
// Handler to get user informationfuncgetUserHandler(w http.ResponseWriter, r*http.Request) {
user:=User{
ID: 1,
Name: "Alice",
Email: "alice@example.com",
Password: "secret",
}
// Hide the password before sending the responseuser.HidePassword()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
funcmain() {
http.HandleFunc("/user", getUserHandler)
fmt.Println("Server is running on port 8080")
http.ListenAndServe(":8080", nil)
}
By using methods, you can encapsulate behavior related to your data types and make your code more organized and modular.
What is Defer:
The defer statement in Go is used to ensure that a function call is performed later in a program’s execution, usually for purposes of cleanup. Deferred function calls are executed in the reverse order that they were deferred, right before the surrounding function returns, regardless of whether the function returns normally or via a panic.
Deferred functions are executed in Last In, First Out (LIFO) order
This means that if you defer multiple function calls, the last one deferred will be the first to execute when the surrounding function returns.
Example:
package main
import"fmt"funcmain() {
fmt.Println("Start of main function")
deferfmt.Println("This is deferred")
fmt.Println("End of main function")
}
O/P:
StartofmainfunctionEndofmainfunctionThisisdeferred
Multiple Deferred Calls:
package main
import"fmt"funcmain() {
fmt.Println("Start of main function")
deferfmt.Println("First deferred call")
deferfmt.Println("Second deferred call")
deferfmt.Println("Third deferred call")
fmt.Println("End of main function")
}
O/P:
StartofmainfunctionEndofmainfunctionThirddeferredcallSeconddeferredcallFirstdeferredcall
Advanced:
Interfaces in GO:
In Go, an interface is a collection of methods that a type can implement. It's a way to define a contract that a type must adhere to, without caring about the underlying implementation.
Interfaces are a way to define a set of method signatures that a type must implement. Unlike other languages, Go’s interfaces are implemented implicitly. This means that a type does not need to explicitly declare that it implements an interface, it just needs to provide the methods that the interface requires
Syntax
An interface in Go specifies a method set, which is a collection of method signatures. Any type that has methods matching the method set of an interface is considered to implement that interface.
package main
import"fmt"// Define a simple interface named 'Describer'typeDescriberinterface {
Describe() string
}
// Implement the interface for a 'Person'typePersonstruct {
NamestringAgestring
}
// Implement the 'Describe' method for 'Person'func (pPerson) Describe() string {
return"Hi, I'm "+p.Name+"and my age is "+p.Age
}
// Implement the interface for a 'Car'typeCarstruct {
Modelstring
}
// Implement the 'Describe' method for 'Car'func (cCar) Describe() string {
return"This is a "+c.Model+" car"
}
// Function to display description using the interfacefuncdisplayDescription(dDescriber) {
fmt.Println(d.Describe())
}
funcmain() {
// Create instances of Person and Carperson:=Person{Name: "Jaddu"}
car:=Car{Model: "BMW"}
// Use the Describe method through the Describer interfacedisplayDescription(person)
displayDescription(car)
}
Explanation:
We define an interface Describer with a single method Describe.
We define a struct type Person and Car.
We implement the Describe method for the Person type and Car type, which makes Person & Car satisfy the Describer interface.