Final, Const, Invariant
David B. Held
dheld at codelogicconsulting.com
Fri Mar 23 00:25:57 PDT 2007
Since the Extended Type Design thread has blown my stack (and taken all
the heap in my mail reader), here is my explanation of these concepts
for anyone who might still be confused. Yes, the explanation is
cartoony, but I hope it helps:
Final
This is the "Velcro(TM)" property. Any variable declared with this
property is like super-glue. You stick a value to it, and it doesn't
let go. You can't pull the value off it no matter how hard you try.
final int x = 42; // uh-oh...what if x doesn't like 42?
x = 5; // oops! x is still stuck to the 42!!
final int y = x; // y is 42
final Bob alice = new Bob(); // Yay! Bob and alice got married!
alice.changeBob(); // ok, final doesn't stop this...
Bob.mutate(alice); // ...or this
alice = pete; // Nope! alice is "monogamous"...no new Bobs for her!
Final is a "storage class" because it doesn't say anything about the
value we are pointing to...just us.
Invariant
This is the IronMan property. This is a type property, so it's a
property of objects, not handles/pointers/references. No matter who
points at you, your skin is an impenetrable alloy, and you remain
steadfastly unchanged:
invariant string s = "Hello, world"; // Yup, this friendly message is
also invariant
s = "Goodbye, world"; // Ok, Invariant doesn't say anything about this
name, only what this name refers to
s = mutableString(); // Nope! The type of s requires that we only
refer to IronMan objects...s is a big fan of IronMan
s.breakWill(); // Ain't gonna happen...this is IronMan, and he can't be
broken!
final invariant string s = "Bonjour, amigo!"; // s has an identity
crisis, but it's permanent :(
s = "Hola, amie!"; // Nope...final means we are married to "Bonjour..."
s.reverse(); // Nuh-uh...our Franish is carved in stone
Const
This is the Rose Colored Glasses property. Also known as the
Look-But-Don't-Touch property. Const variables are
Puritanical...everything they see is invariant, or so they think.
const Point* p = new Point(x, y); // Ok, even though this new Point is
intrinsically mutable, our Rose Colored Glasses make us think it's
really Invariant
p = differentPoint; // Ok, because const is a type qualifier, which
means that it affects what kinds of folks we associate with, but doesn't
stop us from associating altogether
p->getX(); // Ok, because getX() is also const...the underlying Point
remains unchanged
p->move(5, 6); // Wrong! Even though the underlying point is not
invariant, we pretend that it is, because the glasses make us think the
invariance is half-full
final const Point* q = p; // Now we've gone and aliased p, and we can't
undo it
q->move(w, z); // Just as illegal as it was for p
q = new Point(1, 2); // Start over? Fuhggettaboutit
invariant const Point* r = new Point(8, 10); // Redundant, but
legal...the underlying object is immutable, so in this case, the world
Really Is Rose-Colored; we can take the glasses off, but we like the style
final invariant const Point* end = new Point(double.infinity,
double.infinity); // Also redundant, but this is the immutable
unchangeable end of the universe.
Dave
More information about the Digitalmars-d
mailing list