问题
In Dart exists two kind of types.
- Runtime type
- Static type
Here is proof in Dart language specification:
The static type of null is bottom.
- Runtime type of
null
isNull
- Static type of
null
isbottom
This mean that objects in Dart can have two kind of types.
One real type that called static
and one virtual
type that called runtime
.
That is, runtime type of null
is not a bottom
but a regular class Null
.
class Null {
factory Null._uninstantiable() {
throw new UnsupportedError('class Null cannot be instantiated');
}
/** Returns the string `"null"`. */
String toString() => "null";
}
But at the same time value with this regular runtime type Null
can be assigned to any other type because real (static) type of the null
is a bottom
type.
How called this technique in Dart?
The type substitution or something different?
P.S.
This question about static types of values but not about static types of variables that declared with type annotations.
This is because the null
is not a variable but value
with static type
of bottom
.
P.S.
Very curious case (at least for me).
void main() {
Null _null;
String s = _null;
}
I get a warning:
A value of type 'Null' cannot be assigned to a variable of type 'String'
It is quite correct. But at the same time this works.
Сurious thing with type substitution (static and runtime).
回答1:
The runtime type of a Dart value is its class. The static type of a Dart expression is what the static type inference derives it to be, and it belongs to the world of static types. That world is larger than just the classes declared in a program. The type "bottom", the type "dynamic" and the function type "int->int" are all examples of static types that do not correspond to a class.
Or in other words: values have classes, expressions have types (just as in many other languages). There is no "static type of values" because static types exist at compile time, and values exist only at runtime [1].
The static type inference algorithm is specified in the Dart language specification. It is what it is, and all that is required of it is that it is, in some way, compatible with the runtime behavior of the program.
The static type system is a program analysis that attempts to detect likely programming errors, nothing more and nothing less. If you have a static type warning, it is considered likely, but not certain, that you have a bug. The type inference system should give few false warnings, and fail to detect few actual bugs, while also being simple enough to describe, understand and implement.
Picking "bottom" as the type of "null" is just a way to make the static type system match the "assignable" relation between types, which is what assignments check at runtime, without having to check explicitly for "Null" everywhere. It's just an algorithm that happen to give a useful result.
The static type does not exist at runtime. For example, the VM contains no implementation of the static type system at all.
/L
[1] Well, except for compile-time constant expressions.
回答2:
When you declare a class and write type annotations this are static types.
As type annotations are not used at runtime you can assign a value of type Foo
to a variable of type Bar
. Even if the static type is Foo
the runtime type is Bar
.
Might be wrong. I haven't taken a closer look at those matters yet.
来源:https://stackoverflow.com/questions/21871856/what-means-in-dart-static-type-and-why-it-differs-with-runtime-type