Go Tutorial menu

Go Structs, Methods and Interfaces

Go has no classes. Instead it uses structs for data, methods for actions, and interfaces for shared behaviour.

Structs

A struct groups related fields under one name:

Example

go
package main

import "fmt"

type Student struct {
	Name  string
	Age   int
	Marks int
}

func main() {
	s1 := Student{Name: "Ali", Age: 19, Marks: 82}
	s2 := Student{"Ayesha", 20, 91}

	fmt.Println(s1.Name, s1.Marks)
	s2.Marks = 95
	fmt.Println(s2)
	fmt.Printf("%+v\n", s1)
}
Output
Ali 82
{Ayesha 20 95}
{Name:Ali Age:19 Marks:82}

%+v prints the field names too, which helps when debugging.

Field names that start with a capital letter are visible to other packages. Lowercase names stay private to their package.

Methods

A method is a function attached to a type. The receiver appears in brackets before the method name.

Example

go
package main

import "fmt"

type Rectangle struct {
	Width, Height float64
}

func (r Rectangle) Area() float64 {
	return r.Width * r.Height
}

func (r *Rectangle) Scale(f float64) {
	r.Width *= f
	r.Height *= f
}

func main() {
	room := Rectangle{Width: 10, Height: 12}
	fmt.Println(room.Area())
	room.Scale(2)
	fmt.Println(room.Width, room.Height, room.Area())
}
Output
120
20 24 480
ReceiverExampleUse it when
Value(r Rectangle)The method only reads the data
Pointer(r *Rectangle)The method changes the data

A value receiver works on a copy, so changes would be lost. That is why Scale uses a pointer.

Pointers in Short

A pointer holds the address of a value. &x gives the address, and *p reads the value at that address.

Example

go
package main

import "fmt"

func addBonus(marks *int) {
	*marks += 5
}

func main() {
	m := 70
	addBonus(&m)
	fmt.Println(m)
}
Output
75

Interfaces

An interface lists method signatures. Any type that has those methods automatically satisfies the interface. There is no implements keyword.

Example

go
package main

import "fmt"

type Payment interface {
	Pay(amount int) string
}

type Cash struct{}

type Card struct {
	Bank string
}

func (c Cash) Pay(amount int) string {
	return fmt.Sprintf("Paid Rs %d in cash", amount)
}

func (c Card) Pay(amount int) string {
	return fmt.Sprintf("Paid Rs %d with %s card", amount, c.Bank)
}

func checkout(p Payment, amount int) {
	fmt.Println(p.Pay(amount))
}

func main() {
	checkout(Cash{}, 500)
	checkout(Card{Bank: "Meezan"}, 1200)
}
Output
Paid Rs 500 in cash
Paid Rs 1200 with Meezan card

checkout works with any payment type. You can add a new type later, such as a mobile wallet, without changing checkout.

Embedding

A struct can include another struct. Its fields and methods become available directly:

Example

go
type Person struct{ Name string }
type Teacher struct {
	Person
	Subject string
}

With t := Teacher{Person{"Sir Imran"}, "Maths"}, you can write t.Name directly.

Exercise

Exercise

How does a type satisfy an interface in Go?

Learn Go with a teacher

Join the Python Programming course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp