Skip to main content

Dart dynamic type

Dart's dynamic is a special type that can hold any type of value. Although it is possible to return a dynamic to Dart in the form of DartDynamic, it is preferable to return an enum instead that has a variant for each type you want to support.

Example

Let's say you have a struct that can hold either a u32 or a String and some other fields (in a significantly worse design):

struct MyStruct {
a: Optional<u32>,
b: Optional<String>,
}

struct DataStruct {
msg: String,
data: MyStruct,
}

You can define an enum in Rust to represent this:

enum MyEnum {
U32(u32),
String(String),
}

And then you can define a struct that holds this enum:

struct MyStruct {
msg: String,
data: MyEnum,
}

Returning dynamics

Aside from DartOpaque, you may also return a dynamic type to Dart by specifing the return type as DartDynamic. DartDynamic is the umbrella type for all C-representable Dart values, which can be obtained from Rust types that implement IntoDart.

pub fn return_dynamic() -> DartDynamic {
vec![
().into_dart(),
0i32.into_dart(),
format!("Hello there!").into_dart()
].into_dart()
}
final dynamic values = await api.returnDynamic();
assert(values is List<dynamic>);
assert(values[0] == null);
assert(values[1] == 0);
assert(values[2] == "Hello there!");

DartDynamic is not supported as parameters, and structs that transitively include them may not be used in parameter positions either. If you only care about accepting or returning an opaque Dart object without interacting with it, consider DartOpaque.

This type is meant to be used only as an esacpe hatch, if your data cannot be expressed as either a fixed struct or enum.