Null, Nil, None: The Ghost Values That Make Programming Possible
Teqani Blogs
Writer at Teqani
Recently, I was trying to print the memory address of a variable. To my surprise, it turned out to be null. Not a number, not a string, not even garbage data—just nothingness. This exploration delves into the mysterious world of null values in programming languages like Dart, Python, and Swift, uncovering how they are handled in memory and the implications for null safety.
Understanding Null Values
Out of sheer curiosity (and maybe a little mischief), I decided to see what happens in other languages I know, like Python and Swift — and surprise, surprise, I got pretty much the same response. In Python, it’s None casually sitting there like it owns the place. In Swift, it’s nil, all serious and wrapped up in an optional like a strict teacher who won’t let you skip class. And then there’s Dart with its good old null, trying to be practical—friendly enough to show up, but disciplined enough to not ruin everything (thanks to null safety).
We’ve all heard that Dart is a “null-safe” language, which makes it sound like null is finally on a leash. But honestly… what does “null” in null safety really mean? Is it a friendly ghost, a strict teacher, or just a sneaky little gremlin waiting to crash your app when you least expect it?
What Really Happens When You Assign a Value to a Variable
In Dart, when you write:
var name = "Flutter never dies";
print(name); // Flutter never dies
print(name.hashCode); // Some number representing its memory reference
Dart finds a spot in memory to store the string "Flutter never dies". The variable name doesn’t hold the string directly — it points to the memory location where "Flutter never dies" lives. That’s why printing name shows the string, and hashCode gives you a number representing its memory reference. Fair enough, we already know how assigning a value works. But what happens if we don’t assign anything at all or assign null?
Null in Action
Let’s see null in action with a quick Dart example:
void main() {
String? name;
String? nullName = null;
print("HashCode name : ${name.hashCode}");
print("HashCode nullName : ${nullName.hashCode}");
print("HashCode of raw null : ${null.hashCode}");
}
Output All three of them returned the same reference — pretty wild, right? And the funny part? I never even defined null myself. It’s like Python’s None, Swift’s nil, and Dart’s null are sitting in a secret club somewhere, sipping coffee, laughing at us, and thinking, “Yeah, we exist whether you ask for us or not.” I even tried another example just to mess with them… spoiler: they didn’t care.
The Memory Allocation Twist
Remember earlier, when we saw that every variable points to a memory address once a value is assigned? Well, here’s a twist: if another variable gets assigned the same value, it can point to the same memory address!
After some more digging (and a few cups of coffee), I realized that Dart, like many modern languages, tries to be memory-efficient. Instead of creating multiple copies of the exact same object in memory, it can reuse the same instance. It’s kind of like Dart saying:
“Why waste more memory? Let’s just share this object — everyone can sit at the same chair.” And as null is reserved keyword in dart you can check more here.
So basically, when a Dart program runs, null is already chilling in memory. And the magic part? When you assign null to another variable, it just points to that same memory spot—like null has its own VIP lounge—even though you never explicitly created it.
So, after scratching my head and understanding maybe 10% of the whole thing, but this is what my curiosity was able to uncover. Next time someone asks me about these ghostly types, at least I can say something… all thanks to the humble null variable, which somehow managed to sneak a little more knowledge into my brain. Who knew an invisible guest could be such a good teacher?
All blogs are certified by our company and reviewed by our specialists
Issue Number: #48126252-df39-48d3-b1c4-75f1834696be