是否存在本机(支持语言)的延迟评估语法?类似于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);
}
getter非常冗长,并且有重复的代码。 此外,我无法构建构造函数const
,因为缓存变量_res
必须按需计算。我想如果我有一个类似Scala的lazy
功能,那么我也会有一个语言支持来拥有一个常量构造函数。这要归功于懒惰的评估_res
是referentially transparent和would 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);
}
答案 0 :(得分:2)
<强> UPDATE2 强>
来自@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中试用
<强>更新强>
如果计算需要引用实例成员(this.xxx),可重用的Lazy<T>
在Dart中可能如下所示,但也不能与const一起使用,并且不能在字段初始值设定项中使用。
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;
}
}
中试用
<强>原始强>
使用闭包进行延迟评估的http://matt.might.net/articles/implementing-laziness/的Dart版本:
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.
}
中试用
答案 1 :(得分:0)
我认为这个小片段可能对你有帮助......
int _val;
int get val => _val ?? _val = 9;