Summary#
- 셋 모두
Iterable
object를 동일한 element를 가진 새 List
로 copy할 때 사용할 수 있다.
toList()
는 List.of
의 short-hand method로 서로 같다.
List.from
은 original Iterable
의 element들을 runtime에 result type으로 casting하고, casting에 실패하면 runtime error를 발생시킨다.
List.of
는 original Iterable
의 element들이 result type과 같거나 하위 type인지 compile-time에 check하고, type이 호환되지 않으면 compile-time error를 발생시킨다.
List.from
은 original Iterable
을 down casting할 때 사용할 수 있고, List.of
는 up casting할 때 사용할 수 있다.
- Copy 할 때 original type을 지켜야 한다면
toList()
또는 List.of
를 사용하고, type을 변경할 때만 List.from
을 사용하자.
elements
에 Iterable
type을 전달하여 새로운 List
생성
- Definition
external factory List.from(Iterable elements, {bool growable = true});
elements
의 item type을 고려하지 않기 때문에 새로 생성하는 list의 item type을 지정하지 않으면 List<dynamic>
으로 생성됨
final nums = [1, 2, 3]; // List<int>
final dynamicList = List.from(nums);
print(dynamicList.runtimeType); // List<dynamic>
- 새로 생성하는 list의 item type을 지정하면
elements
의 item type이 type casting됨
final nums = [1, 2, 3]; // List<int>
final numList = List<num>.from(nums);
print(numList.runtimeType); // List<num>
- 새로 생성하는 list의 item type이 runtime에 결정된다. 즉, compile-time에 type check를 하지 않는다.
String
type인 "3"
을 int
로 직접 type casting 할 수 없으므로 type error가 발생한다.
final nums = [1, 2, "3"]; // List<Object>
// TypeError: "3": type 'String' is not a subtype of type 'int'
final intList = List<int>.from(nums);
double
type인 3.0
은 int
로 casting 가능하므로 runtime error가 발생하지 않지만, 여전히 compile time에는 알 수 없다.
final nums = [1, 2, 3.0]; // List<num>
final intList = List<int>.from(nums);
print(intList.runtimeType); // List<int>
elements
에 Iterable
type을 전달하여 새로운 List
생성 => 역할은 List.from
과 같음
- Definition
external factory List.of(Iterable<E> elements, {bool growable = true});
elements
의 item type과 새로 생성하는 list의 item type이 같으므로, 생성하는 list의 item type을 지정하지 않으면 elements
의 item type을 따라간다.
final nums = [1, 2, 3]; // List<int>
final = List.of(nums);
print(intList.runtimeType); // List<int>
- 새로 생성하는 list의 item type을 지정하면
elements
의 item type도 같은 type이어야 한다. elements
에 다른 item type을 가진 list를 전달하면 compile error가 발생한다.
final nums = <num>[1, 2, 3]; // List<int>
// Error: The argument type 'List<num>' can't be assigned to the parameter type 'Iterable<int>'.
final intList = List<int>.of(nums);
- 단, 새로 생성하는 list의 item type이
elements
item type의 상위 type이라면 up casting 될 수 있다.
final nums = [1, 2, 3]; // List<int>
final = List<num>.of(nums);
print(intList.runtimeType); // List<num>
List<E> toList({bool growable = true}) => List<E>.of(this, growable: growable);
List.of
의 shortcut method
List.of
로 감싸는 대신 toList()
를 사용하는게 더 간단하다.
Don’t use List.from
unless you intent to change the type of the result#
- Effective Dart 문서에서는 result type을 의도적으로 바꾸고 싶을 때만
List.from
을 사용하도록 제한한다.
- 이외에 original
Iterable
과 result List
의 element type이 같은 경우에는 List.of
또는 toList()
를 사용한다.
List.of
도 공통된 상위 type으로 up casting이 가능하지만, original type을 유지하지 않는 경우에는 모두 List.from
을 사용하는게 일관성을 지킬 수 있을 것 같다.