Reputation: 28926
Some magic is going on which is shaking my basics:
void main() {
method(['1', '2']); // fails
final list = ['1', '2'];
method(list); // works
}
void method(List<Object> objects) {
List<String> strings = objects;
}
Can anyone explain the reason behind this magic?
Upvotes: 0
Views: 58
Reputation: 71723
Dart type inference infers missing types for an expression based on the expectations of the surrounding context and on the types of the sub-expressions. It gives more weight to the "context type".
In the first case method(['1', '2']);
, the context type of the list literal is List<Object>
. That's the parameter type of method
. Since the only type missing from the list literal is the list element type itself, and List<Object>
is what is being asked for, the compiler infers method(<Object>['1', '2']);
.
That creates a List<Object>
, passes it to method
, which then tries to down-cast that to List<String>
. That fails because a List<Object>
is not a List<String>
, not even if all its members are (currently) strings.
In the second case, final list = ['1', '2'];
there is no context type. So, lacking that, the element type is inferred from the actual elements. Since they are all strings, the compiler infers final list = <String>['1', '2'];
.
That List<String>
is then passed to method
as a List<Object>
(that's fine because a List<String>
is a List<Object>
), and it's then down-cast back to List<String>
, which works because it is one.
So, the difference is in the context type of the list literal.
Upvotes: 2