Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic 消息传递和方法调用之间有什么区别?_Language Agnostic_Message Passing_Method Invocation - Fatal编程技术网

Language agnostic 消息传递和方法调用之间有什么区别?

Language agnostic 消息传递和方法调用之间有什么区别?,language-agnostic,message-passing,method-invocation,Language Agnostic,Message Passing,Method Invocation,消息传递和方法调用之间有区别吗,或者可以认为它们是等效的?这可能是特定于语言的;许多语言不支持消息传递(尽管我能想到的所有语言都支持方法),而支持消息传递的语言可以有完全不同的实现。此外,根据语言的不同,方法调用也有很大的差异(C语言与Java语言、Lisp语言与您最喜欢的语言)。我相信这是语言不可知论。对于已传递的方法,您能做什么,而对于已调用的方法,您不能做什么,反之亦然(在您最喜欢的语言中) 消息传递和方法调用之间有区别吗,或者可以认为它们是等效的 他们很相似。一些差异: 消息可以同步或异

消息传递和方法调用之间有区别吗,或者可以认为它们是等效的?这可能是特定于语言的;许多语言不支持消息传递(尽管我能想到的所有语言都支持方法),而支持消息传递的语言可以有完全不同的实现。此外,根据语言的不同,方法调用也有很大的差异(C语言与Java语言、Lisp语言与您最喜欢的语言)。我相信这是语言不可知论。对于已传递的方法,您能做什么,而对于已调用的方法,您不能做什么,反之亦然(在您最喜欢的语言中)

消息传递和方法调用之间有区别吗,或者可以认为它们是等效的

他们很相似。一些差异:

消息可以同步或异步传递(例如,Windows中SendMessage和PostMessage之间的差异)

您可能在不确切知道要将消息发送到哪个远程对象的情况下发送消息


目标对象可能位于远程计算机或O/S上。

实际上它们并不相同。消息传递是在两个或多个并行进程之间传输数据和指令的一种方式。方法调用是调用子例程的一种方式。Erlang的并发性是建立在前一个概念的基础上的,具有面向并发的编程功能

消息传递很可能涉及方法调用的一种形式,但方法调用不一定涉及消息传递。如果它这样做了,那就是传递消息。消息传递是在并行进程之间执行同步的一种形式。方法调用通常意味着同步活动。调用方等待方法完成,然后才能继续。消息传递是协同程序的一种形式。方法调用是子例程的一种形式


所有的子例程都是协同例程,但所有的协同例程都不是子例程。

作为第一近似值,答案是:无,只要您“行为正常”

尽管许多人认为有——从技术上讲,通常是一样的:缓存查找要为特定命名操作执行的代码段(至少在正常情况下是这样)。将操作名称称为“消息”或“虚拟方法”并没有什么区别

但是:Actor语言确实不同:在拥有活动对象时(每个对象都有一个隐式消息队列和一个工作线程——至少在概念上是这样),并行处理变得更容易处理(谷歌还“通信顺序进程”了解更多)

但是:在Smalltalk中,可以包装对象,使其与actor相似,而无需实际更改编译器、语法甚至重新编译

但是:在Smalltalk中,当您尝试发送接收方不了解的消息(即“someObject foo:arg”)时,将创建一个包含名称和参数的消息对象,并将该消息对象作为参数传递给“doesNotUnderstand”消息。因此,对象可以自行决定如何处理未实现的消息发送(也称为未实现方法的调用)。当然,它可以将它们推到队列中,让工作进程对它们进行排序

当然,这在静态类型语言中是不可能的(除非您大量使用反射),但实际上这是一个非常有用的特性。代理对象、按需加载代码、远程过程调用、学习和自修改代码、调整和自优化程序、corba和dcom包装器、工作队列都是基于该方案构建的。当然,它可能被误用,并导致运行时错误。 所以它是一把双面剑。犀利有力,但新手手中危险


编辑:我在这里写的是语言实现(正如在java与SimalTalk中的一样,不是进程间的机制。

irc,它们已经被正式证明是等价的。至少不用花太多的思考来表示它们应该是。大概需要的是,暂时忽略调用地址与内存中的实际点的直接等价性,并将其简单地视为一个。从这个角度来看,数字只是一个抽象标识符,它唯一地标识您希望调用的特定类型的功能

即使在同一台机器中调用函数,也不需要被调用的地址直接指定物理地址(甚至虚拟地址)被调用函数的地址。例如,虽然几乎没有人真正使用它们,但Intel保护模式任务门允许直接调用任务门本身。在这种情况下,只有地址的段部分被视为实际地址——即,对任务门段的任何调用最终都会调用相同的地址,regardle如果需要,处理代码可以检查指定的偏移量,并使用它来决定要调用的单个方法——但是指定的偏移量和被调用函数的地址之间的关系可以完全是任意的

成员函数调用只是一种消息传递类型,它提供(或至少促进)一种常见情况下的优化,即所讨论的服务的客户端和服务器共享一个公共地址空间。抽象服务标识符与该服务的提供者所在的地址之间的1:1对应关系允许从一个到另一个的简单、异常快速的映射

同时,不要搞错:看起来像成员函数调用的事实并不妨碍它在另一台机器上实际执行或异步执行,或(经常)两者都执行。实现这一点的典型机制是代理函数,它将成员函数调用的“虚拟消息”转换为可以(例如)根据需要通过网络传输的“真实消息”(例如,M
class MyClass {
    void doSomething() {}
}

class AnotherClass {
    void someMethod() {
        Object object = new Object();
        object.doSomething(); // compiler checks and complains that Object contains no such method.

        // However, through an explicit cast, you can calm the compiler down,
        // even though your program will crash at runtime
        ((MyClass) object).doSomething(); // syntactically valid, yet incorrect
    }
}