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
}
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 {
}
callbacks
calling a function by passing another function as an argument to the function.
f func(func(int,int) int), int) int
Memory
In Go variables are passed by value not by reference.
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++
}
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"
}
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
}
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
}
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
}
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",
})
}
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.")
}
}
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"
}
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
}
}
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
}
- 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)
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())
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())
}
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)
}
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)
}
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)
}
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)
}
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)
}
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])
}
Top comments (0)