Menu
Coddy logo textTech

Getter & Setter Methods

Part of the Object Oriented Programming section of Coddy's GO journey — lesson 49 of 107.

Since unexported fields can't be accessed directly from outside a package, you need to provide methods that allow controlled access. These are commonly called getters and setters.

In Go, the convention for getters is simple: use the field name with an uppercase first letter. Don't prefix with "Get"—just use Balance(), not GetBalance():

type BankAccount struct {
    balance int  // unexported
}

// Getter - returns the value
func (b *BankAccount) Balance() int {
    return b.balance
}

// Setter - modifies the value with validation
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

The real power of setters is adding validation or business logic. Instead of letting external code set any value directly, you control what's allowed:

func (b *BankAccount) Deposit(amount int) bool {
    if amount <= 0 {
        return false
    }
    b.balance += amount
    return true
}

This Deposit method acts as a specialized setter that enforces rules—no negative deposits allowed. External code must go through your methods, ensuring the struct always remains in a valid state. This is encapsulation in action: hiding the data while exposing controlled behavior.

challenge icon

Challenge

Easy

Let's build a temperature converter that demonstrates proper encapsulation using getter and setter methods. You'll create a struct that stores temperature internally in Celsius but provides controlled access through methods with validation.

You'll organize your code across two files:

  • temperature.go: Create a Temperature struct with an unexported celsius field (float64). Implement the following methods:
    • Celsius() - a getter that returns the current temperature in Celsius
    • SetCelsius(value float64) - a setter that only accepts values at or above absolute zero (-273.15). If the value is below this threshold, the temperature should remain unchanged.
    • Fahrenheit() - returns the temperature converted to Fahrenheit using the formula: (celsius * 9/5) + 32
    • SetFahrenheit(value float64) - converts the input from Fahrenheit to Celsius and stores it, but only if the resulting Celsius value is at or above -273.15
    Also add a constructor NewTemperature(celsius float64) *Temperature that creates a temperature initialized to the given value (assume valid input for the constructor).
  • main.go: Read temperature values from input and demonstrate the getter/setter methods. Create a temperature, display its values in both units, then attempt to set new values and show the results.

The following inputs will be provided:

  • Line 1: Initial Celsius value
  • Line 2: New Celsius value to set
  • Line 3: New Fahrenheit value to set

Format all temperature outputs with two decimal places. Print the following sequence:

  1. After creation: C: [celsius] F: [fahrenheit]
  2. After setting Celsius: C: [celsius] F: [fahrenheit]
  3. After setting Fahrenheit: C: [celsius] F: [fahrenheit]

For example, given 25, -300, and 212, your output should be:

C: 25.00 F: 77.00
C: 25.00 F: 77.00
C: 100.00 F: 212.00

Notice that the second line shows unchanged values because -300 is below absolute zero, so the setter rejected it. The third line shows the temperature after successfully setting 212°F (which converts to 100°C). This is the power of setters—they enforce rules that keep your data valid.

Cheat sheet

Unexported fields require getter and setter methods for controlled access from outside the package.

Getter Convention

In Go, getters use the field name with an uppercase first letter. Don't prefix with "Get":

type BankAccount struct {
    balance int  // unexported
}

// Getter - returns the value
func (b *BankAccount) Balance() int {
    return b.balance
}

Setter with Validation

Setters modify values and can include validation or business logic:

// Setter - modifies the value with validation
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

Specialized Setters

Create methods that enforce specific rules instead of allowing direct value assignment:

func (b *BankAccount) Deposit(amount int) bool {
    if amount <= 0 {
        return false
    }
    b.balance += amount
    return true
}

This approach ensures encapsulation: hiding data while exposing controlled behavior, keeping structs in a valid state.

Try it yourself

package main

import (
	"fmt"
)

func main() {
	// Read input values
	var initialCelsius float64
	var newCelsius float64
	var newFahrenheit float64
	fmt.Scanln(&initialCelsius)
	fmt.Scanln(&newCelsius)
	fmt.Scanln(&newFahrenheit)

	// TODO: Create a new Temperature using the constructor

	// TODO: Print initial values in format "C: [celsius] F: [fahrenheit]" with 2 decimal places

	// TODO: Attempt to set new Celsius value and print the result

	// TODO: Attempt to set new Fahrenheit value and print the result
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming