out模式和out模式之间的区别?到目前为止我收集的信息是 我知道的主要区别是,无论是进出模式,实际参数都会被改变,即使写作和阅读也是可能的,那么主要区别是什么才能帮助我理解?
答案 0 :(得分:2)
差异的最佳解释是RM 6.4.1(11-15)。
从语义上讲,只有通过复制传递的参数才有区别。如果调用具有in out
参数的子程序,则实际参数在调用之前应具有合法值。在输入时,子程序复制变量并检查以确保它满足约束条件。
对于out
参数,实际参数不需要输入值;它可能是未初始化的垃圾。目的是子程序在子程序设置之前不会使用该参数的值(它可以通过赋值或作为out
参数传递给其他子程序来设置,或者a Default_Value
,或者通过其他方式)。但是,这并没有强制执行。
在某些情况下,这会导致不同的行为。例如:
subtype Int10 is Integer range 1 .. 10;
procedure Proc (Param : in out Int10) is
begin
Param := 5;
end Proc;
Y : Integer := 100;
...
Proc (Y);
由于Param
是in out
参数,因此会在输入时检查约束。因此,对Proc(Y)
的调用会引发Constraint_Error
。但是:
subtype Int10 is Integer range 1 .. 10;
procedure Proc (Param : out Int10) is
begin
Param := 5;
end Proc;
Y : Integer := 100;
...
Proc (Y);
在这种情况下,不会引发Constraint_Error
。实际上,Y
根本不需要初始化,因为期望该过程不会使用输入值。根据RM,对于某些类型的参数类型,该值甚至不被复制。所以在这种情况下:
Save_Param : Integer;
procedure Proc (Param : out Int10) is
begin
Save_Param := Param; -- legal but not recommended
Param := 5;
end Proc;
Y : Integer := 3;
...
Proc (Y);
Save_Param
可能会被设置为某个垃圾值,而不是3
。 (在Ada 2012中,有一个Default_Value
方面可以应用于子类型;在这种情况下,out
参数将设置为此默认值而不是未初始化的垃圾,而in out
参数1}}参数仍然会从实际参数中获取值。)
对于通过引用传递的参数,行为确实没有区别。
Ada 83的规则不同。具有in out
参数的子程序可以读取和写入该参数,而允许具有out
参数的子程序分配给参数但是不可以执行任何操作读取该参数的值(除非某些情况下无法读取判别式)。因此:
procedure Proc (Param : out Int10) is
begin
Param := 5;
Save_Param := Param; -- illegal in Ada 83, legal in Ada 95 and later versions
end Proc;
换句话说,out
参数确实只有out
put- 。然而,在Ada 95中放宽了规则,因为程序员发现它太具有限制性。