// good case
var points = <Point>[];
var addresses = <String, Address>{};
var counts = <int>{};
// bad case
var addresses = Map<String, Address>();
var counts = Set<int>();
-> 해당 예제는 named 생성자에 적용하지 않음, List.from(), Map.fromIterable() 등 비슷한 생성자들은 저마다 사용법이 존재함 (List 클래스 또한 unnamed 생성자가 존재하지만, null safe Dart에서는 사용이 금지됨)
// good case
var arguments = [
...options,
command,
...?modeFlags,
for (var path in filePaths)
if (path.endsWith('.dart')) path.replaceAll('.dart', '.js')
];
// bad case
var arguments = <String>[];
arguments.addAll(options);
arguments.add(command);
if (modeFlags != null) arguments.addAll(modeFlags);
arguments.addAll(filePaths
.where((path) => path.endsWith('.dart'))
.map((path) => path.replaceAll('.dart', '.js')));
// good case
if (lunchBox.isEmpty) return 'so hungry...';
if (words.isNotEmpty) return words.join(' ');
// bad case
if (lunchBox.length == 0) return 'so hungry...';
if (!words.isEmpty) return words.join(' ');
// good case
for (final person in people) {
...
}
// bad case
people.forEach((person) {
...
});
주어진 Iterable를 사용해서 동일한 요소를 가지는 새로운 List를 만드는 확실한 방법은 아래 두가지가 대표적
var copy1 = iterable.toList();
var copy2 = List.from(iterable);
위 둘의 명백한 차이는 첫 번째가 더 간결하고 원래 객체의 타입 인자를 보전한다는 것
// Creates a List<int>:
var iterable = [1, 2, 3];
// good casse
// Prints "List<int>":
print(iterable.toList().runtimeType);
// bad case
// Prints "List<dynamic>":
print(List.from(iterable).runtimeType);
// good case
var numbers = [1, 2.3, 4]; // List<num>.
numbers.removeAt(1); // Now it only contains integers.
var ints = List<int>.from(numbers);
타입에 대해 신경스찌 않거나, 단지 iterable를 복사하고 원래 타입을 보존하는 것이 목적이라면, toList()를 사용한다
var objects = [1, 'a', 2, 'b', 3];
var ints = objects.whereType<int>();
// good case
var stuff = <dynamic>[1, 2];
var ints = List<int>.from(stuff);
// bad case
var stuff = <dynamic>[1, 2];
var ints = stuff.toList().cast<int>();
// good case
var stuff = <dynamic>[1, 2];
var reciprocals = stuff.map<double>((n) => 1 / n);
// bad case
var stuff = <dynamic>[1, 2];
var reciprocals = stuff.map((n) => 1 / n).cast<double>();
올바른 타입으로 생성한다 -> 컬렉션이 처음 생성되는 코드를 수정하여 올바른 타입을 가지게 한다
요소에 접근할 때 캐스팅을 시도한다 -> 해당 컬렉션에 반복을 수행한다면, 반복 내부에서 각 요소를 캐스팅한다
List.from()을 사용하여 캐스팅하도록 한다 -> 컬렉션의 모든 요소에 접근을 끝냈고 원본 객체가 더 이상 필요하지 않다면, List.from()을 사용하여 타입을 변환한다
// good case
List<int> singletonList(int value) {
var list = <int>[];
list.add(value);
return list;
}
// bad case
List<int> singletonList(int value) {
var list = []; // List<dynamic>.
list.add(value);
return list.cast<int>();
}
// good case
void printEvens(List<Object> objects) {
// List에 int만 존재한다는 것을 알고 있습니다.
for (final n in objects) {
if ((n as int).isEven) print(n);
}
}
// bad case
void printEvens(List<Object> objects) {
// List에 int만 존재한다는 것을 알고 있습니다.
for (final n in objects.cast<int>()) {
if (n.isEven) print(n);
}
}
// good case
int median(List<Object> objects) {
// List에 int만 존재한다는 것을 알고 있습니다.
var ints = List<int>.from(objects);
ints.sort();
return ints[ints.length ~/ 2];
}
// bad case
int median(List<Object> objects) {
// List에 int만 존재한다는 것을 알고 있습니다.
var ints = objects.cast<int>();
ints.sort();
return ints[ints.length ~/ 2];
}