是否有 native (支持语言)的惰性评估语法?像Scala中的lazy val这样的东西。

我经历了the docs,找不到任何东西。只有一章关于“延迟加载库”,但这不是我要的。

基于这项研究,我倾向于相信(如果我错了,请纠正我)当前没有这种事情。但是,也许您知道将提供该功能的任何计划或功能请求?还是Dart团队考虑并拒绝了它?

如果确实对此没有本地支持,那么实现惰性评估的最佳实践(最佳语法)是什么?一个例子将不胜感激。

编辑:

我正在寻找的功能的优势与其他语言的实现几乎相同:Scala's lazy val C#'s Lazy<T> Hack's __Memorize attribute:

  • 简洁语法
  • 延迟计算,直到需要该值为止
  • 缓存结果(需要的惰性)
  • 不要破坏纯函数范式(下面的解释)

  • 一个简单的例子:
    class Fibonacci {
    
      final int n;
      int _res = null;
    
      int get result {
        if (null == _res) {
          _res = _compute(this.n);
        }
        return _res;
      }
    
      Fibonacci(this.n);
    
      int _compute(n) {
        // ...
      }
    }
    
    main(List<String> args) async {
      print(new Fibonacci(5).result);
      print(new Fibonacci(9).result);
    }
    

    setter/getter 非常冗长,并且具有重复的代码。 此外,我不能将构造函数const设为,因为必须根据需要计算缓存变量_res。我想像一下,如果我具有类似Scala的lazy功能,那么我还将获得具有常量构造函数的语言支持。这要归功于这样的事实,即懒惰求值的_resreferentially transparentwould not be in the way
    class Fibonacci {
    
      final int n;
      int lazy result => _compute(this.n);
    
      const Fibonacci(this.n);  // notice the `const`
    
      int _compute(n) {
        // ...
      }
    }
    
    main(List<String> args) async {
      // now these makes more sense:
      print(const Fibonacci(5).result);
      print(const Fibonacci(9).result);
    }
    

    最佳答案

    更新2

    来自@lrn的评论-使用Expando进行缓存使其可以与const一起使用:

    class Lazy<T> {
      static final _cache = new Expando();
      final Function _func;
      const Lazy(this._func);
      T call() {
        var result = _cache[this];
        if (identical(this, result)) return null;
        if (result != null) return result;
        result = _func();
        _cache[this] = (result == null) ? this : result;
        return result;
      }
    }
    
    
    defaultFunc() {
      print("Default Function Called");
      return 42;
    }
    main([args, function = const Lazy(defaultFunc)]) {
      print(function());
      print(function());
    }
    

    在DartPad中尝试

    更新

    在Dart中,可重用的Lazy<T>看起来像下面的样子,但是它也不适用于const,并且如果计算需要引用实例成员(this.xxx),则不能在字段初始化程序中使用。
    void main() {
      var sc = new SomeClass();
      print('new');
      print(sc.v);
    }
    
    class SomeClass {
      var _v  = new Lazy<int>(() {
        print('x');
        return 10;
      });
      int get v => _v();
    }
    
    class Lazy<T> {
      final Function _func;
      bool _isEvaluated = false;
      Lazy(this._func);
      T _value;
      T call() {
        if(!_isEvaluated) {
          if(_func != null) {
            _value = _func();
          }
          _isEvaluated = true;
        }
        return _value;
      }
    }
    

    DartPad中尝试

    原始

    Dart版本的http://matt.might.net/articles/implementing-laziness/使用闭包来懒惰求值:
    void main() {
      var x = () {
        print ("foo");
        return 10;
      }();
      print("bar");
      print(x);
      // will print foo, then bar then 10.
      print('===');
      // But, the following Scala program:
      x = () {
        print("foo");
        return 10;
      };
      print ("bar");
      print (x());
      // will print bar, then foo, then 10, since it delays the computation of x until it’s actually needed.
    }
    

    DartPad中尝试

    关于dart - 如何在Dart中进行惰性评估?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33218987/

    10-12 07:11