我有3个文件:other.ads,other.adb和test.adb。
other.ads:
package Other is
type Thing is tagged record
Stuff : String(1..4);
end record;
procedure Say (T : in Thing);
end Other;
other.adb:为简洁而未显示,并且对于该示例不是必需的。
test.adb:
with Other;
procedure Test is
T : Other.Thing := new Other.Thing;
begin
T.Stuff := "test";
T.Say;
end Test;
我收到此错误:
test.adb:4:23: expected type "Thing" defined at other.ads:2
test.adb:4:23: found type access to "Thing" defined at line 4
如果我改为使用这些文件:
other.ads:
package Other is
type Thing is tagged record
Stuff : String(1..4);
end record;
type Ref is access all Thing;
procedure Say (T : in Thing);
end Other;
test.adb:
with Other;
procedure Test is
T : Other.Ref := new Other.Thing;
begin
T.Stuff := "test";
T.Say;
end Test;
然后编译并运行正常。
为什么我不能将new Other.Thing
指定为Other.Thing
类型?
答案 0 :(得分:4)
如果在Java中声明变量,则设置它的方式取决于变量的类型是否是原始的。 int foo
为整数保留空间。另一方面,Thing foo
为Thing
的参考(指针)保留空间,并使用new
为Thing
本身保留空间; Thing foo = new Thing
。
Ada不是那样的(就此而言,C或C ++也不是这样);当你说Foo : Thing
时,编译器会在那里为Thing
保留空间(可能在堆栈上)。所以你的第一个例子可以阅读
T : Other.Thing;
begin
T.Stuff := “test”;
在Ada中使用new
关键字的时间是出于某种原因需要访问值的时间,正如您在第二个示例中强制要求的那样;您已将T
声明为Ref
,声明为access all Thing
。
请注意,在您的第二个示例中,当您说
时 T.Stuff := “test”;
这实际上是
的简写 T.all.Stuff := “test”;
有些人喜欢明确地放置.all
。
答案 1 :(得分:2)
T
的类型是access type,指向Other.Thing
类型的对象,因为您使用new
指定了allocator。您还可以简单地声明Other.Thing
类型的对象,并使用aggregate对其进行初始化。
with Ada.Text_IO;
procedure Test is
package Other is
type Thing is tagged record
Stuff : String(1..4);
end record;
end Other;
S : Other.Thing := (Stuff => "test");
T : access Other.Thing := new Other.Thing;
begin
Ada.Text_IO.Put_Line(S.Stuff);
T.Stuff := "test";
Ada.Text_IO.Put_Line(T.Stuff);
end Test;