Brett Sutton
Brett Sutton

Reputation: 4584

Return value for Dart cascade

I'm trying to use the Dart cascade operator to implement a builder pattern.

I have this (hacked) class:

import 'package:test/test.dart';
class Scope
{
   
   void value<T>(ScopeKey<T> key, T value) {}
   R run<R>(R Function() callback) => callback();
}

int use(String key) => 18;

I want to use a cascade to call the 'run' method which should return a value.

What I want to do is:

      final ageKey = ScopeKey<int>();
      final age = Scope()
       ..value<int>(ageKey, 18);
       .run<int>(() => use(ageKey));

      expect(age, equals(18));

Note the single '.' before 'run'.

What I have to do is:

   final ageKey = ScopeKey<int>();
      final scope = Scope()..value<int>(ageKey, 18);

      final age = scope.run<int>(() => use(ageKey));

      expect(age, equals(18));

My understanding is that .. discards the result of the value call and instead returns the Scope object.

So Scope()..value() should return a Scope.

As such I'm expecting the call

Scope()..value().run() => 1

to return 1 as the left hand operand to run should be the Scope object.

Instead it generates a compile error:

This expression has a type of 'void' so its value can't be used. Try checking to see if you're using the correct API; there might be a function or call that returns void you didn't expect. Also check type parameters and variables which might also be

This implies that .run is using the return value of value.

What am I misunderstanding here?

Upvotes: 1

Views: 619

Answers (1)

mmcdon20
mmcdon20

Reputation: 6736

You can add parenthesis so that .run is called on your Scope.

final age = (Scope()..value<int>(ageKey, 18)).run<int>(() => use(ageKey));

With cascades you can currently do things like this:

class Collection<T> {
  List<T> items = [];
  @override
  String toString() => 'Items($items)';
}

void main() {
  final items = Collection<int>()
    ..items.add(1);
  print(items);
}

This only works because .add is called on items rather than Collection. The downside is if you wanted to call a method on Collection after the cascade call you have to wrap the expression in parenthesis.

Upvotes: 1

Related Questions