Difference between dynamic and static type in Dart
In regard to the first question, there will be no difference in what each msg
variable contains.
For the Map question, the reason for specifying the type of a variable that is constructed at declaration is to allow some flexibility with subclasses. Take for example the following code:
class SubMap extends Map { SubMap() : super();}Map map = new SubMap();
Here we have a variable map
which contains a SubMap
object as its value, however we are allowing it to contain values of type Map
(or other types which subclass Map
) at later times.
The main thing to remember with Dart is that it is optionally typed. When running your code, none of your type annotiations make any difference at all (unless you run in checked mode). What the type annotations are for is to help your IDE and other tools provide autocomplete help, possible warnings, etc. which other fully dynamic languages like Javascript cannot.
String msg = "Hello world.";msg = "Hello world again.";msg = 1; // exception in checked mode - int can not be assigned to String.var msg = "Hello world.";msg = "Hello world again.";msg = 1; // ok in checked mode
Checked mode is the developer mode where type annotations are checked and create runtime exceptions when code violates them.
In unchecked (production) mode it makes no difference if you add a type annotation and which one. This is for performance reasons because checked mode is slower.
The declaration Map myMap = new Map()
does three things:
- it declares a variable named
myMap
with type-annotationMap
, - it creates a new object using the
Map
constructor, and - it assigns the object to the variable.
The type annotation means that myMap
has static type Map
. The static type can give you some warnings at compile time, but it doesn't change anything at runtime.The type annotation also adds a type check in checked mode, where any assignment to the variable is checked for being assignable to Map
.
The object you create could be any object using any constructor. I regularly use new HashMap()
instead of new Map()
, and still assign it to a variable typed as Map
.
Then the object is assigned to the variable, and the type check succeeds, if in checked mode.
The variable is independent of the value used to initialize it. If you later assign a string to the myMap
variable, it will fail in checked mode.
So, the difference between the two msg
variables is that one has a static type and a type check in checked mode.For the code you show, there is no difference in behavior.
If the next line was var y = msg + 42;
, then the typed version would give a warning (msg
has static type String
, and String.operator+
has type String->String
, so the 42
has an invalid argument type), where the untyped version wouldn't warn you (msg
has type dynamic
so you probably know what you are doing).