Immutability

Search for a command to run...

No comments yet. Be the first to comment.
This blog series explores the depth and versatility of the Rust programming language through powerful lenses such as Object-Oriented Programming (OOP), Functional Programming (FP), and Design Patterns.
Object-oriented programming, also called OOP, is a programming style that is dependent on the concept of objects. It is very popular and established. It is like designing and organizing your code by thinking of parts of your program as real-world obj...
Iterators are a fundamental concept in programming that enable you to process a sequence of items, such as elements in a collection, one at a time, without revealing the collection's internal structure. They form the backbone of operations like loopi...

A closure is an anonymous function that can capture variables from its environment. At a high level, Rust closures allow you to write small, concise functions inline, without having to formally define a new fn with a name. They’re particularly handy ...

Object-oriented programming, also called OOP, is a programming style that is dependent on the concept of objects. It is very popular and established. It is like designing and organizing your code by thinking of parts of your program as real-world obj...

Traits are the most important topic to understand the design patterns in Rust. Traits are fundamental feature in Rust that provide a way for shared behavior, abstraction and polymorphish. You can think of traits as interfaces in other programming la...

Immutability is a cool concept in programming that C++ questions with "why?" It means that once you create a variable or object, you can't change its state. This idea somewhat opposes object-oriented concepts, yet it's crucial for writing clean, maintainable, and concurrency-friendly code. An immutable data structure can't be changed directly—any operation that seems to change it actually creates a new object or structure with the updated value, leaving the original unchanged. Different programming languages like Rust, C++, and Java have their own methods for handling immutability.
In Rust, immutability is a core feature and is enforced by the language's ownership and borrowing system. Variables are immutable by default. Once a value is assigned to a variable, it cannot be changed unless explicitly declared as mutable.
let x = 5; // x is immutable
// x = 6; // This would cause a compile-time error
let mut y = 10; // y is mutable
y = 20; // This is allowed
Rust's immutability ensures thread safety and prevents data races. Immutable data can be shared across threads without the risk of concurrent modification. Rust's borrow checker enforces rules around mutable and immutable references to ensure memory safety.
Rust’s borrowing system ensures memory safety:
Any number of immutable references (&T) to a resource is allowed simultaneously.
You can have either a single mutable reference (&mut T) or any number of immutable references, but not both at the same time.
If you have a struct instance that is immutable, then its fields are also immutable—you can't change them.
struct Point {
x: i32,
y: i32,
}
let p = Point { x: 1, y: 2 }; // p is immutable
// p.x = 3; // This would cause a compile-time error
C++ does not enforce immutability by default, but it provides tools to achieve it. Variables are mutable unless explicitly marked as const. The const keyword is used to declare immutable variables or pointers.
const int x = 5; // x is immutable
// x = 6; // This would cause a compile-time error
In C++, you can mark member functions as const to indicate that they do not modify the object's state.
class Point {
public:
int getX() const { return x; } // This function does not modify the object
private:
int x;
};
Java provides immutability through the final keyword and immutable classes. The final keyword is used to declare immutable variables, methods, or classes.
final int x = 5; // x is immutable
// x = 6; // This would cause a compile-time error
In Java, immutable classes are created by making all fields final and not providing setters.
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
}
Embrace immutability where you can, and you’ll find your code more predictable, maintainable, and (in many cases) faster or easier to optimize.