Is int type in Dart a value type or reference type?
What is "reference type","value type","canonicalized" in Dart? (concrete definition)
I was looking into the specific definitions of "reference type" and "value type", but in the end, I thought it would be good to understand the code that represents the difference and the behavior (result) of that code.
If possible, I would like Dart code, but if it has the same structure as Dart regarding the above issues, there is no problem in other languages, so I would appreciate it if you could give me sample code.
CodePudding user response:
The meaning of "reference type" and "value type" used here is the distinction made by C#.
A reference type is a traditional object-oriented object. It has identity which it preserves over time. You can have two objects with the same state, but they are different objects.
You don't store reference type values directly into variables. Instead you store a reference to them. When you access members of the object, you do so through the reference (x.foo
means "evaluate x
to a reference, then access the foo
member of the object referenced by that reference).
When you check for identity, identical(a, b)
, you check whether two different references refer to the same object.
A value type does not have identity. It's defined entirely in terms of its state, its contents. When you assign a value type to a variable, you make a copy of it. It's the "value" in call-by-value. C# allows you to declare value types with that behavior. (Reference types do not correspond to call-by-reference, rather to call-by-sharing.)
In Dart, all objects are reference objects. This differs from, say, Java, where an int
is a value-type ("primitive type" in their parlance), and they have a separate Integer
class which can wrap the int
values and is a reference type. That's needed because Integer
is a subtype of Object
, but int
isn't, so you can't store int
values in a generic container which expects a subtype of Object
.
In Dart, some reference types are still more value-like than others. In particular numbers.
A Dart number, like the integer 1
, has precisely one object representing that value. If you write 1
in different places of the program, or even calculate 4 ~/ 4
or 3 - 2
, you always get the same object representing the value 1. It's like it's not an object at all, and identical
only compares values. And that's precisely what happens, because it allows the compiler to treat integers as primitive values internally, and not worry about sometimes having to give you the same 1
object back that you put in.
This is sometimes expressed as integers being "canonicalized": There is only one canonical instance representing each state.
Dart also canonicalizes other objects. Constant expressions are canonicalized, so that two different constant expressions generating instances of the same type, with identical states, are made to return the same, canonical, instance representing that value. Since the value is guaranteed to be immutable, there is no need to have equal objects with different identities. (If they were mutable, it matters very much which one you mutate and which one you don't).