Dart 的“Expando”功能是啥,它有啥作用?
Posted
技术标签:
【中文标题】Dart 的“Expando”功能是啥,它有啥作用?【英文标题】:What is the Dart "Expando" feature about, what does it do?Dart 的“Expando”功能是什么,它有什么作用? 【发布时间】:2012-11-01 17:18:20 【问题描述】:最近在 Dart 中使用了“Expando”一词。听起来不错。 API 没有为我提供太多线索。
一两个例子可能最有帮助!
(不确定这是否相关,但我最渴望向类添加方法(getter)和/或变量的方法。希望这可能是解决这个问题的关键。(提示:我正在使用Nosuchmethod 方法现在并希望能够返回未找到方法的值。))
提前致谢,
_swarmii
【问题讨论】:
【参考方案1】:Expandos 允许您将对象与其他对象相关联。一个非常有用的例子是 html DOM 元素,它本身不能被子类化。让我们做一个***扩展来为元素添加一些功能 - 在这种情况下,typedef 语句中给出了 Function 签名:
typedef CustomFunction(int foo, String bar);
Expando<CustomFunction> domFunctionExpando = new Expando<CustomFunction>();
现在使用它:
main()
// Assumes dart:html is imported
final myElement = new DivElement();
// Use the expando on our DOM element.
domFunctionExpando[myElement] = someFunc;
// Now that we've "attached" the function to our object,
// we can call it like so:
domFunctionExpando[myElement](42, 'expandos are cool');
void someFunc(int foo, String bar)
print('Hello. $foo $bar');
【讨论】:
这和 Map只是为了澄清 expando 和地图之间的区别:正如 groups 中所报告的,expando 有弱引用。 这意味着即使键仍然存在于 expando 中(只要没有其他对它的引用),它也可以被垃圾回收。
对于所有其他意图和目的,它是一张地图。
【讨论】:
【参考方案3】:我玩了一下。这就是我所拥有的。
import 'dart:html';
const String cHidden = 'hidden';
class ExpandoElement
static final Expando<ExpandoElement> expando =
new Expando<ExpandoElement>("ExpandoElement.expando");
final Element element;
const ExpandoElement._expand(this.element);
static Element expand(Element element)
if (expando[element] == null)
expando[element] = new ExpandoElement._expand(element);
return element;
// bool get hidden => element.hidden; // commented out to test noSuchMethod()
void set hidden(bool hidden)
if (element.hidden = hidden)
element.classes.add(cHidden);
else
element.classes.remove(cHidden);
noSuchMethod(InvocationMirror invocation) => invocation.invokeOn(element);
final Expando<ExpandoElement> x = ExpandoElement.expando;
Element xquery(String selector) => ExpandoElement.expand(query(selector));
final Element input = xquery('#input');
void main()
input.classes.remove(cHidden);
assert(!input.classes.contains(cHidden));
input.hidden = true;
assert(x[input].hidden); // Dart Editor warning here, but it's still true
assert(!input.classes.contains(cHidden)); // no effect
input.hidden = false;
assert(!x[input].hidden); // same warning, but we'll get input.hidden via noSuchMethod()
assert(!input.classes.contains(cHidden));
x[input].hidden = true;
assert(input.hidden); // set by the setter of ExpandoElement.hidden
assert(input.classes.contains(cHidden)); // added by the setter
assert(x[input].hidden);
assert(x[input].classes.contains(cHidden)); // this is input.classes
x[input].hidden = false;
assert(!input.hidden); // set by the setter
assert(!input.classes.contains(cHidden)); // removed by the setter
assert(!x[input].hidden);
assert(!x[input].classes.contains(cHidden));
// confused?
assert(input is Element);
assert(x[input] is! Element); // is not
assert(x[input] is ExpandoElement);
assert(x is Expando<ExpandoElement>);
【讨论】:
在我发布这个的那天,Dart 版本是 r19425以上是关于Dart 的“Expando”功能是啥,它有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章