user3612643
user3612643

Reputation: 5772

How to model recursive structure in Dart

I am having problems with modelling a structure where a Node has a child of a type Child that extends Node. Please look at the following simplified problem.

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
}

At recurse(child), the compilation fails with

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

What am I doing wrong?

Upvotes: 0

Views: 186

Answers (1)

lrn
lrn

Reputation: 71723

I'm assuming you have either the no_implicit_downcast lint enabled, or you are using the null safe Dart experiment. In either case, assigning Node<dynamic> to Node<Node<dynamic>> is an implicit downcast, which is not allowed.

The type Node<Node<dynamic>> is a super-bounded type. It's what you get when you write just Node, because there is no finite type which satisfies Child extends Node<Child>. Inference will decorate your code to:

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

which is what causes your failure.

What you can do is to explicitly change the recurse function into:

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

Upvotes: 1

Related Questions