Variable 'valor' is of type 'Object'.
'valor' stores a 'Map<String, String>'.
I can 'convert' valor to a Map using:
var json = valor as Map<String, String>;
The question is: Can I do the same thing without using 'as' ?
CodePudding user response:
Sorry but you can't, even method such as Iterable.cast()
are using the as
keyword under the hood.
You can check the Dart type system documentation for confirmation.
CodePudding user response:
You can and should check if valor
is a Map<String, String>
first and allow it to be automatically type-promoted:
if (valor is Map<String, String>) {
// `valor` is now known to be a `Map<String, String>`.
var json = valor;
...
}
Note that type promotion can occur only for local variables, so if valor
is not local, you must create a local reference first.
CodePudding user response:
You can cast without an explicit as
, by going through dynamic.
dynamic dynamicValue = valor; // Valid up-cast.
Map<String, String> map = dynamicValue; // Implicit down-cast.
The implicit downcast is effectively an as Map<String, String>
which is inserted by the compiler.
When compiling for the web, with "unsound optimizations" enabled, the implicit cast is optimized away and the compiler just blindly treats the value as a Map<String, String>
, whether it is one or not.
If that's your goal, to avoid the cost of a cast at runtime, you can also just do:
Map<String, String> json = valor as dynamic;
That as
is an up-cast, which is always sound and has no runtime overhead.
(Depending on your analyzer configuration, you may get warnings about implicit downcasts.)
Another approach, which doesn't use as
, but does cost at runtime, is to use promotion:
Map<String, String> json;
if (valor is Map<String, String>) { // no `as`, but still a check.
json = valor;
} else {
throw UnsupportedError("But it should be a map!");
}
// json is assigned here.
No use of as
, but just as many type checks as as Map<String, String>
does, so maybe not what you want anyway.