DEV Community

Back2Basics
Back2Basics

Posted on

Go Lang Part - 02

In this blog post we will discuss a bit more on the Go lang.

Functions

Functions in Go can take zero or more arguments.

To make Go code easier to read, the variable type comes after the variable name.
Example: Accepts two integers and returns subtraction result.

func sub(x int, y int) int {
  return x-y
}
Enter fullscreen mode Exit fullscreen mode

Multiple parameters

When multiple arguments are of the same type, the type only needs to be declared after the last one, assuming they are in order.
If they are not in order they need to be defined seperately.

Example:

func add(x, y int) int {
  return x + y
}

func somename(firstname , lastname string, age int) int {
}
Enter fullscreen mode Exit fullscreen mode

callbacks

calling a function by passing another function as an argument to the function.

 f func(func(int,int) int), int) int
Enter fullscreen mode Exit fullscreen mode

Memory

In Go variables are passed by value not by reference.

Image description
The below code even though the increment function 5+1 but in the main() function has still 5.

func main(){
  x := 5
  increment(x)
  fmt.Println(x)
  // 5

}
func increment(x int){
   x++
}
Enter fullscreen mode Exit fullscreen mode

If we want the value in main updated then return x.

Return multiple values

func main(){
   firstName, lastName := getNames()
   fmt.Println("Welcome to Textio,", firstName,lastName)
   // Welcome to Textio JohnDow
   firstName, _ := getNames() // _ for unwanted variables.
   fmt.Println("Welcome ", firstName)
}
func getNames() (string, string) {
   return "John", "Dow"
}
Enter fullscreen mode Exit fullscreen mode

Automatically return values initialized in the other function.

func getCoords() (x, y int){
  var x int
  var y int
  return x,y
}
// same
func getCoords() (int, int){
  var x int
  var y int
  return // automatically returns x and y
}
func getCoords() (int, int){
  var x int
  var y int
  return 5,6 // explicit returns 5 and 6
}
func getCoords() (x int,y int){
  // do something
  return  // named returns x and y
}
Enter fullscreen mode Exit fullscreen mode

Early returns

if divisor is 0 then return error. else return actual division result.

func divide(dividend, divisor int) (int, error){
   if divisor == 0 {
      return 0, errors.New("Can't divide by zero")
   }
   return dividend/divisor, nil
}
Enter fullscreen mode Exit fullscreen mode

nil: This is the second return value, which corresponds to the error type in the function's signature. Since there is no error in this case (i.e., when the divisor is not zero), we return nil, which means "no error."

Structs in Go

Struct in Go used to group different types of variables together.

type car struct {
  Make string
  Model string
  Height int
  Width int
}
Enter fullscreen mode Exit fullscreen mode

Similar to dictionary in Python.

package main
import "fmt"

type messageToSend struct {
  phoneNumber int
  message string
}

func test(m messageToSend){
  fmt.Printf("Sending message: '%s' to : %v\n", m.message, m.phoneNumber)
}

func main(){
   test(messageToSend{
       phoneNumber: 123456,
       message: "thanks for singing up",
    })
}
Enter fullscreen mode Exit fullscreen mode

Struct key can hold any type of data

package main

import "fmt"

// Nested struct

type messageToSend struct {
  message    string
  sender     user
  recipient  user
}

type user struct {
  name   string
  number int
}

func canSendMessage(mToSend messageToSend) bool {
  if mToSend.sender.name == "" {
    return false
  }
  if mToSend.sender.number == 0 {
    return false
  }
  if mToSend.recipient.name == "" {
    return false
  }
  if mToSend.recipient.number == 0 {
    return false
  }
  return true
}

func test(m messageToSend) {
  fmt.Printf("Sending message: '%s' to: %s at number %d\n", m.message, m.recipient.name, m.recipient.number)
}

func main() {
  sender := user{name: "John", number: 123456}
  recipient := user{name: "Jane", number: 654321}

  message := messageToSend{
    message:   "Thanks for signing up!",
    sender:    sender,
    recipient: recipient,
  }

  // Check if the message can be sent
  if canSendMessage(message) {
    test(message)
  } else {
    fmt.Println("Message cannot be sent due to missing information.")
  }
}

Enter fullscreen mode Exit fullscreen mode

Anonymous Structs in Go

An anonymous struct is just like a normal struct, but it is defined without a name and therefore cannot be referenced elsewhere in the code.

To create an anonymous struct, just instantiate the instance immediately using a second pair of brackets after declaring the type:

myCar := struct {
   Make string
   Model string
}{
   Make: "telsa",
   Model: "model 3"
}
Enter fullscreen mode Exit fullscreen mode

We can even nest anonymous structs as fields within other structs:

type car struct {
  Make string
  Model string
  Height int
  Width int
  Wheel struct {
     Radius int
     Material string
  }
}
Enter fullscreen mode Exit fullscreen mode

When want to use once we can go for anonymous structs.

Embeded structs

It follows data-only inheritance that can be useful at times.

type car struct {
  make string
  model string
}
type truck struct{
   car
   bedSize int
}
Enter fullscreen mode Exit fullscreen mode
  • Embedded structs fields are accessed at the top-level, unlike nested structs.
  • Promoted fields can be accessed like normal fields except that they cant be used in composite literals.
lanesTruck := truck {
    bedSize: 10,
    car: car{
      make: "toyota",
      model: "camry",
   },
}

fmt.Println(lanesTruck.bedSize)

fmt.Println(lanesTruck.make)
fmt.Println(lanesTruck.model)

Enter fullscreen mode Exit fullscreen mode

Lets go with an example

type rect struct{
  width int
  height int
}
func (r rect) area() int {
   return r.width * r.height
}
// instantiating struct
r := rect{
   width: 5,
   height: 10,
}

fmt.Println(r.area())
Enter fullscreen mode Exit fullscreen mode

Image description

Interfaces

Interfaces are collections of method signatures. A type "implementations" an interface if it has all of the methods of the given interface defined on it.
Example without implementing the shape interface we are calculating the area,perimeter.

package main

import (
    "fmt"
    "math"
)

type shape interface {
    area() float64
    perimeter() float64
}

type rect struct {
    width, height float64
}

func (r rect) area() float64 {
    return r.width * r.height
}

func (r rect) perimeter() float64 {
    return 2 * (r.width + r.height)
}

type circle struct {
    radius float64
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

func (c circle) perimeter() float64 {
    return 2 * math.Pi * c.radius
}

func main() {
    fmt.Println("Try programiz.pro")

    // Create instances of rect and circle
    r := rect{width: 5, height: 10}
    c := circle{radius: 7}
        var s shape = c 
    // Declare a slice of shapes
    fmt.Printf("Shape: %T\n", s)
    fmt.Printf("Area: %.2f\n", s.area())
    fmt.Printf("Perimeter: %.2f\n", s.perimeter())

        s = r
    fmt.Printf("Shape: %T\n", s)
    fmt.Printf("Area: %.2f\n", s.area())
    fmt.Printf("Perimeter: %.2f\n", s.perimeter())

}
Enter fullscreen mode Exit fullscreen mode

Arrays

Collection of same type of values stored in contagious. Indexed from 0 to length of array.
Example Array of integers

package main
import "fmt"
func main(){
   grades := [4]int{100,32,50,60}
   fmt.Printf("Grades: %v", grades)

}

Enter fullscreen mode Exit fullscreen mode

Image description

Example Array of strings

package main
import "fmt"

func main(){
   var students [3] string
   fmt.Printf("Students: %v\n", students)
   students[0] = "Lisa"
   students[1] = "Ahmed"
   students[2] = "arnold"
   fmt.Printf("Students: %v\n", students)
}
Enter fullscreen mode Exit fullscreen mode

Image description

Example matrix

package main
import "fmt"

func main() {
   var identityMatrix [3][3]int
   identityMatrix[0] = [3]int{1,0,0}
   identityMatrix[1] = [3]int{0,1,0}
   identityMatrix[2] = [3]int{0,0,1}
   fmt.Println(identityMatrix)
}
Enter fullscreen mode Exit fullscreen mode

Image description

Copy an array

Copying the array will only copies the values of the array not addresses.

package main
import "fmt"

func main() {
   a := [...]int{1,2,3}
   b := a
   b[1] = 5
   fmt.Println(a)
   fmt.Println(b)
}
Enter fullscreen mode Exit fullscreen mode

Image description

If we use &a the we are pointing to the a array address.

package main
import "fmt"

func main() {
   a := [...]int{1,2,3}
   b := &a
   b[1] = 5
   fmt.Println(a)
   fmt.Println(b)
}
Enter fullscreen mode Exit fullscreen mode

Slice

Initialized as a literal :.

package main
import "fmt"

func main() {
   a := []int{1,2,3,6,8,6}
   b := a
   b[1] = 5
   fmt.Println(a)
   fmt.Println(b)
   fmt.Println("Length: ",len(a))
   fmt.Println("Capacity: ",cap(a))
   fmt.Println("Slice of all elements", a[:])
   fmt.Println("Slice of 3 to end index elements", a[3:])
   fmt.Println("Slice of 0 to 5 index elements", a[:6])
   fmt.Println("Slice of 3 to 5th index elements", a[3:6])
}
Enter fullscreen mode Exit fullscreen mode

Image description

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please show some love ❤️ or share a kind word in the comments if you found this useful!

Got it!