Как моделировать рекурсивную структуру в Dart

#dart

#dart

Вопрос:

У меня возникли проблемы с моделированием структуры, в которой у Node есть дочерний элемент типа, Child который расширяется Node . Пожалуйста, посмотрите на следующую упрощенную задачу.

 abstract class Node<Child extends Node<dynamic>> {
  Node(this.child);
  final Child child;
}

class FooNode extends Node<BarNode> {
  FooNode() : super(BarNode());
}

class BarNode extends Node {
  BarNode() : super(null);
}

void recurse(Node node) {
  final child = node.child;
  recurse(child);  // <--- FAILS
}
  

При recurse(child) компиляция завершается с ошибкой

 The argument type 'Node<dynamic>' can't be assigned to the parameter type 'Node<Node<dynamic>>'.dartargument_type_not_assignable
  

Что я делаю не так?

Комментарии:

1. Это в dartpad компилируется просто отлично

2. Вы включили строгий режим?

Ответ №1:

Я предполагаю, что у вас либо включен параметр no_implicit_downcast lint, либо вы используете эксперимент с нулевым безопасным Dart. В любом случае присвоение Node<dynamic> Node<Node<dynamic>> является неявным понижением, что недопустимо.

Тип Node<Node<dynamic>> является сверхограниченным типом. Это то, что вы получаете, когда пишете просто Node , потому что не существует конечного типа, который удовлетворяет Child extends Node<Child> . Вывод украсит ваш код, чтобы:

 void recurse(Node<Node<dynamic>> node) {
  final Node<dynamic> child = node.child;
  recurse(child);  // <--- FAILS
}
  

именно это и является причиной вашего сбоя.

Что вы можете сделать, так это явно изменить recurse функцию на:

 void recurse(Node<dynamic> node) {
  final child = node.child as Node<dynamic>;
  recurse(child);
}