我想做什么
給定以下節點:class Node<T> _/span>{
Node(this.value)。
T值。
Node? child。
//TODO:添加`visit`方法。
String toString() => value.toString() 。
}
我想添加一個visit方法,它將對每個節點及其子節點的值遞回地執行一些操作。然后我可以做這樣的事情:
void main() {
final root = Node(1) 。
root.child = Node(2);
root.child!.child = Node(3)。
//其中的一個。
root.visit(print)。
root.visit((value) => print(value))。
//1
// 2; // 2
//3 //3
}
天真的解決方案
如果我做了下面的事情,就可以作業了:如果我做了下面的事情,就可以作業了。
void visit(Function action) {
action(value)。
child?.visit(action)。
}
天真的解決方案存在的問題
然而,這個陳述句中的value被推斷為dynamic:
root.visit((value) => print(value))。
我想把它推斷為與Node的通用T型別相同。
此外,編譯器還允許以下情況,這將導致運行時崩潰:
root.visit(() => 42) 。
我希望這是一個編譯時錯誤。
我希望這是一個編譯時錯誤。
嘗試的解決方案1
如果我把visit改為如下:
void visit(Function(T value) action) {
action(value)。
child?.visit(action(value))。
}
在編譯時一切看起來都很好:
root.visit(print); // ok
root.visit((value) => print(value)); // OK
root.visit(() => 42); /錯誤。
但是如果我注釋掉最后一個,并在前兩個中的任何一個上運行代碼,那么我將得到以下運行時錯誤:
未處理的例外:
。
型別'Null'不是型別'(dynamic) => dynamic'的子型別
我不太清楚那是什么意思。
嘗試的解決方案 2
添加了void:
void visit(void Function(T value) action) {
action(value)。
child?.visit(action(value)); //error
}
這個運算式的型別是 "void",所以它的值不能被使用。 試著檢查一下你是否使用了正確的API;可能有一個函式或呼叫會回傳你沒有想到的void。也要檢查型別引數和變數,它們也可能是無效的。(dartuse_of_void_result)
嘗試性的解決方案3
這個方案只是在黑暗中捅了一刀:void visit(void Function< T> (T value) action) {
action(value)。
child?.visit(action)。
}
visit方法似乎可以編譯,但是像以前那樣呼叫它,會出現編譯時錯誤:
root.visit(print); /錯誤
root.visit((value) => print(value)); //錯誤
錯誤的內容是:
引數型別'void Function(Object?)'不能分配給引數型別'void Function(T)'。(dartargument_type_not_assignable)
相關的問題
這些問題似乎是相關的,但我想不出如何從中提取解決方案:這些問題似乎是相關的,但我想不出如何從中提取解決方案。
- 如何在Dart中創建一個泛型方法?
- Dart中帶有通用型別引數的回呼
- Dart。在抽象類中覆寫通用函式時發生型別錯誤
- 如何在Dart中檢查和投擲泛型引數?
- Dart傳遞泛型函式<T>(T t)似乎需要澆注,所有其他方式的簽名都不匹配
我怎樣才能解決這個問題呢?
uj5u.com熱心網友回復:
感謝評論中的@jamesdlin 解決了這個問題。
你需要將child的通用型別設定為Node<T>。然后你可以指定方法簽名為void visit(Function(T value) action),并將action本身傳遞給子物件。
以下是完整的例子:
void main() {
final root = Node(1) 。
root.child = Node(2);
root.child!.child = Node(3)。
//這些之一。
root.visit(print)。
root.visit((value) => print(value)); //value 推斷為int。
//root.visit(() => 42); //編譯時錯誤。
// 1
//2 //2
// 3 // 3
}
class Node<T> {
Node(this.value)。
T值。
Node<T>? child。
void visit(Function(T value) action) {
action(value)。
child?.visit(action)。
}
@override
String toString() => value.toString();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/318605.html
標籤:
上一篇:在C#中,我如何將T動態地傳入services.AddHostedService<T>()?
下一篇:通過通用型別查找鍵的輸入
