试图使函数通用,但挂断了

时间:2011-01-11 15:47:49

标签: ada

这是我的问题。我有一个包中的变量(在这种情况下为rec),需要在从包3调用时设置它,但它是私有的。以前函数“set_true”只将rec设置为true,所以这不是什么大问题。但我有另一个包执行相同的处理(我给出了一个简单的例子,但我的文字情况更复杂),所以我想,我可以传入我想要修改的变量,并让它改变。是在下面的布局中设置“rec”的唯一方法,在包1中创建第二个函数,调用set_true并使用rec作为参数?我想避免不得不继续创建其他函数来处理局部变量。我无法将变量移动到public(spec),因为我试图遵循约定,这个变量的“类型”在其他任何地方都不公开,我不希望任何人能够自己设置它(我希望功能必须设置)。我不想创建一个名为例如“set_local_true”的第二个函数,并且创建一个没有参数的重载函数set_true,调用set_true(value => rec)似乎看似具有欺骗性,是否有人有任何更好的建议有我的限制吗?

我的两个要求:
   1.不能公开局部变量    2.能够使用该函数在外部和内部计算内容。

package one is
 procedure set_true(value : out Boolean);
end one;

package body one is
   rec : Boolean;
begin
 procedure set_true(value : out Boolean)
 begin
  value := true;
 end set_true;
end one;

package body two is
 local_rec : Boolean;
begin
  procedure call_function is
   begin
     one.set_true(value => local_rec);
  end call_function;
end two;

package body three is
begin
  procedure call_function is
  begin
    one.set_true(value => <PACKAGE ONE'S REC))
  end call_function;
end three;

编辑:或许,对于函数来说,更好的命名约定是指定他们正在修改该包的本地变量? Set_Local_True再次具有欺骗性,如果你从包3中调用它,你没有设置你的本地为真,你将包的本地设置为真......

2 个答案:

答案 0 :(得分:1)

首先,这是非常愚蠢的代码。我会假设它是其他东西的简写。但是如上所述,我可以向您保证,您的客户可以自己设置自己的布尔值而无需编写例程来为他们执行此操作。事实上,他们可以做得更好。对于这个答案的其余部分,我假设你并没有实际编写变量来为人们设置布尔值,而是做一些实际使用的东西。如果没有,请忽略此答案的其余部分,只删除您的愚蠢程序。

其次,如果您使用单个out参数创建例程,那么除非对象恰好非常大,否则您应该将其设为函数。这将允许您的客户在他们选择时使用函数式编程。你拥有它的方式,可怜的程序员必须停下来创建一个特殊的变量来调用你的例程,即使他们只想做一次。

第三,我不是为每个州使用唯一的设定例程,而是通常更喜欢传入请求的状态。

function Set_Frobnost (New_State : boolean := true) return boolean;

如果状态真的是真正的布尔值(将来没有可能的第三种状态),那么它是有争议的。但是,如果您的客户可能已经将状态存储在变量中(或通过它循环),那么它对您的客户来说可能是一个很大的优势。

您对命名的编辑显示我已走在正确的轨道上。

你应该做两件事之一。

  1. 找到由该变量控制的更高级别的概念,并在此之后命名“setter”例程。
  2. 彻底解决问题并将标志变量放入pacakge规范中。

答案 1 :(得分:1)

如果您必须访问私有变量,则可以在子包中执行此操作。

package One is
   procedure Foo (X : Boolean);
private
   One_Private : Boolean;
end One;

然后

package body One.Two is
    procedure Bar is
       One.Foo (One.One_Private);
    end Bar;
end One.Two;

包的“私有”部分中的元素类似于C ++ / Java中的“受保护”实体。无法从其他任何地方访问真正的私有变量(仅在包体中)。