我嘗試撰寫一個簡單的通用方法,該方法將迭代地復制嵌套List的List<List<int>>. 但不幸的是,遞回呼叫似乎總是 return List<dynamic>,所以我收到以下錯誤
The argument type List<dynamic> can't be assigned to the parameter type T
List<T> listDeepCopy<T>(List<T> list){
List<T> newList = List<T>();
list.forEach((value) {
if( value is List ){
newList.add(listDeepCopy(value)); // <-- listDeepCopy() always returns List<dynamic>
}
else{
newList.add(value);
}
});
return newList;
}
所以如果我打電話
List<List<int>> list = [[1,2],[3,4]];
List<List<int>> copy = listDeepCopy(list);
T是List<int>
value是T——即List<int>
listDeepCopy(value)應該等于listDeepCopy<List<int>>,這將回傳 a List<int>,應該可以添加到newList,這是 aList<List<int>>
我在哪里出錯了,我怎樣才能做這樣的事情?
uj5u.com熱心網友回復:
我可能會將其實作為:
List<T> listDeepCopy<T>(List<T> list) {
var copy = list.toList();
for (var i = 0; i < copy.length; i = 1) {
var element = copy[i];
if (element is List) {
copy[i] = listDeepCopy(element) as T;
}
}
return copy;
}
void main() {
List<List<int>> list = [
[1, 2],
[3, 4]
];
List<List<int>> copy = listDeepCopy(list);
list[0][0] = 99;
print(copy); // Prints: [[1, 2], [3, 4]]
}
您的方法的一個問題是 Dart 無法正確推斷該遞回listDeepCopy(value)呼叫的泛型型別引數。是已知為 avalue的型別(它是 的簡寫),我不知道提取靜態元素型別的方法。(也許@lrn 會看到這一點并提供更好、更完整的解釋。)TListList<dynamic>
List在這種情況下,最好通過呼叫回傳自身副本的方法來依賴多型性: .toList().
(作為一個重要的例子,考慮一個淺拷貝場景:
List<T> shallowCopy1<T>(List<T> list) => <T>[...list];
List<T> shallowCopy2<T>(List<T> list) => list.toList();
extension StaticType<T> on T {
Type get staticType => T;
}
void main() {
List<num> list = <int>[1, 2, 3];
var copy1 = shallowCopy1(list);
var copy2 = shallowCopy2(list);
print('original: staticType: ${list.staticType}, runtimeType: ${list.runtimeType}');
print('copy1: staticType: ${copy1.staticType}, runtimeType: ${copy1.runtimeType}');
print('copy2: staticType: ${copy2.staticType}, runtimeType: ${copy2.runtimeType}');
}
盡管兩個副本都保留了原始的靜態List型別,但只copy2保留了物件的實際(運行時)型別。正確的副本取決于被復制物件的運行時型別,唯一可靠的方法是讓物件創建自身的副本。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/437832.html
下一篇:如何使用動態泛型撰寫結構?
