Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Dart, what's the difference between List.from and .of, and between Map.from and .of?

In Dart, what's the difference between List.from and List.of, and between Map.from and Map.of? Their documentation is not totally clear:

/** * Creates a [LinkedHashMap] instance that contains all key/value pairs of * [other]. * * The keys must all be instances of [K] and the values of [V]. * The [other] map itself can have any type. * * A `LinkedHashMap` requires the keys to implement compatible * `operator==` and `hashCode`, and it allows `null` as a key. * It iterates in key insertion order. */ factory Map.from(Map other) = LinkedHashMap<K, V>.from;  /** * Creates a [LinkedHashMap] with the same keys and values as [other]. * * A `LinkedHashMap` requires the keys to implement compatible * `operator==` and `hashCode`, and it allows `null` as a key. * It iterates in key insertion order. */ factory Map.of(Map<K, V> other) = LinkedHashMap<K, V>.of;  /** * Creates a list containing all [elements]. * * The [Iterator] of [elements] provides the order of the elements. * * All the [elements] should be instances of [E]. * The `elements` iterable itself may have any element type, so this * constructor can be used to down-cast a `List`, for example as: * ```dart * List<SuperType> superList = ...; * List<SubType> subList = *     new List<SubType>.from(superList.whereType<SubType>()); * ``` * * This constructor creates a growable list when [growable] is true; * otherwise, it returns a fixed-length list. */ external factory List.from(Iterable elements, {bool growable: true});  /** * Creates a list from [elements]. * * The [Iterator] of [elements] provides the order of the elements. * * This constructor creates a growable list when [growable] is true; * otherwise, it returns a fixed-length list. */ factory List.of(Iterable<E> elements, {bool growable: true}) =>   new List<E>.from(elements, growable: growable); 

Is the difference related to generics? Maybe the .from factories let you change the type of the list, while the .of ones do not? I come from a Java background, which works with type erasure, and maybe types are reified in Dart and you cannot use casts or raw types to change list/map types?

like image 622
MarcG Avatar asked May 13 '18 20:05

MarcG


People also ask

What is difference between list and map in Dart?

List, Set, Queue are iterable while Maps are not. Iterable collections can be changed i.e. their items can be modified, add, remove, can be accessed sequentially. The map doesn't extend iterable.

What is a list in Dart?

A List is simply an ordered group of objects. The dart:core library provides the List class that enables creation and manipulation of lists. The logical representation of a list in Dart is given below − test_list − is the identifier that references the collection. The list contains in it the values 12, 13, and 14.

What is the difference between dynamic and object in Dart?

There is actually no difference between using Object and dynamic in the example you have given here. There is no practical difference, and you can swap the two and the program will run the same. When I refer to "semantic difference", I mean how the code will be understood by other Dart programmers.

How do you get data from a list in Dart?

try using . indexWhere and use a filter that includes all of your data. (https://www.kindacode.com/snippet/dart-flutter-get-the-index-of-a-specific-element-in-a-list/#:~:text=In%20Dart%2C%20the%20List%20class,that%20satisfies%20the%20given%20conditions.)


1 Answers

The important difference between the from and of methods are that the latter have type annotations and the former do not. Since Dart generics are reified and Dart 2 is strongly typed, this is key to both ensuring the List/Map is correctly constructed:

List<String> foo = new List.from(<int>[1, 2, 3]); // okay until runtime. List<String> bar = new List.of(<int>[1, 2, 3]); // analysis error 

And ensuring that the types are inferred correctly:

var foo = new List.from(<int>[1, 2, 3]); // List<dynamic> var bar = new List.of(<int>[1, 2, 3]); // List<int> 

In Dart 1 types were completely optional, so many APIs were untyped or partially typed. List.from and Map.from are good examples, since the Iterable/Map passed into them doesn't have a type parameter. Sometimes Dart can figure out what the type of this object should be, but sometimes it just ended up as List<dynamic> or Map<dynamic, dynamic>.

In Dart 2 the type dynamic was changed from being both a top (Object) and bottom (null) type to only being a top type. Thus if you created a List<dynamic> accidentally in Dart 1 you could still pass it to a method which required a List<String>. But in Dart 2 List<dynamic> is almost the same as List<Object>, so this would fail.

If you are using Dart 2, you should always use the typed version of these APIs. Why do the old ones still exist, and what are the plans there? I don't really know. I would guess they would be phased out over time, along with the rest of the Dart 1.

like image 164
Jonah Williams Avatar answered Sep 28 '22 02:09

Jonah Williams