gpt4 book ai didi

scope - dart 方法调用上下文

转载 作者:行者123 更新时间:2023-12-03 02:51:54 25 4
gpt4 key购买 nike

我使用下面的代码来查看 dart 如何调用传入其他方法的方法,以查看传入方法将/可以在什么上下文下调用。

void main() {

var one = new IDable(1);
var two = new IDable(2);

print('one ${caller(one.getMyId)}'); //one 1
print('two ${caller(two.getMyId)}'); //two 2
print('one ${callerJustForThree(one.getMyId)}'); //NoSuchMethod Exception

}

class IDable{
int id;
IDable(this.id);

int getMyId(){
return id;
}
}

caller(fn){
return fn();
}

callerJustForThree(fn){
var three = new IDable(3);
three.fn();
}

那么caller管理器如何在没有上下文的情况下调用其参数fn,即one.fn(),以及为什么 callerJustForThree 无法在为其定义了该函数的对象上调用传入的 fn

最佳答案

在 Dart 中,声明为类的一部分的实例方法与其他函数(如闭包和静态函数)之间存在差异。

实例方法是唯一可以访问 this 的方法(构造函数除外) 。从概念上讲,它们是类描述的一部分,而不是对象。也就是说,当您执行方法调用 o.foo() 时Dart 首先提取 o 的类类型。然后它搜索 foo在类描述中(如果需要,递归地遍历父类(super class))。最后它应用找到的方法 this设置为o .

除了能够调用对象 ( o.foo() ) 上的方法之外,还可以获得绑定(bind)闭包: o.foo (没有调用的括号)。然而,这一点至关重要,这种形式只是 (<args>) => o.foo(<args>) 的语法糖。 。也就是说,这只是创建了一个捕获 o 的新闭包。并将对其的调用重定向到实例方法。

整个设置有几个重要的后果:

  • 您可以分离实例方法并获得绑定(bind)闭包。 o.foo的结果自动绑定(bind)到o 。不需要自己绑定(bind)它(但也没有办法将它绑定(bind)到不同的实例)。在您的示例中,这就是 one.getMyId作品。您实际上得到以下关闭:() => one.getMyId()相反。

  • 无法向对象添加或删除方法。您需要更改类描述,而这是(故意)不支持的。

  • var f = o.foo;意味着你总是得到一个新的结束。这意味着您不能使用此绑定(bind)闭包作为哈希表中的键。例如,register(o.foo)接下来是 unregister(o.foo)很可能不起作用,因为每个 o.foo 都会不同。您可以通过尝试 print(o.foo == o.foo) 轻松看到这一点.

  • 您无法将方法从一个对象转移到另一个对象。无论您尝试如何访问实例方法,它们都将始终被绑定(bind)。


看看你的例子:

  print('one ${caller(one.getMyId)}');             //one 1
print('two ${caller(two.getMyId)}'); //two 2
print('one ${callerJustForThree(one.getMyId)}'); //NoSuchMethod Exception

这些行相当于:

 print('one ${caller(() => one.getMyId())}');
print('two ${caller(() => two.getMyId())}');
print('one ${callerJustForThree(() => one.getMyId())}';

内部callerJustForThree :

callerJustForThree(fn){
var three = new IDable(3);
three.fn();
}

给定的参数fn被完全忽略。做的时候three.fn()在最后一行 Dart 会找到 three 的类描述(即 IDable ),然后搜索 fn在里面。由于找不到,它将调用 noSuchMethod倒退。 fn参数被忽略。

如果您想根据某个参数调用实例成员,您可以重写最后一个示例,如下所示:

main() {
...
callerJustForThree((o) => o.getMyId());
}

callerJustForThree(invokeIDableMember){
var three = new IDable(3);
invokeIDableMember(three);
}

关于scope - dart 方法调用上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16450980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com