问题
In Ada, I have the following spec file:
GENERIC
TYPE Item IS PRIVATE; --type of array
size : integer; --size of array
PACKAGE gwar IS
function get_size return integer;
END gwar;
And body file:
with Ada.Text_Io;
use Ada.Text_Io;
package body gwar is
--Get_Size allows the txt file to specify how much space to allocate.
function get_size return Integer is
Filename : String := "win.txt";
File : Ada.Text_IO.File_Type;
Line_Count : Integer := 0;
ReturnSize : Integer;
begin
Ada.Text_IO.Open(File => File,
Mode => Ada.Text_IO.In_File,
Name => Filename);
while Line_Count /= 1 loop
declare
Line : String := Ada.Text_IO.Get_Line(File);
begin
ReturnSize := Integer'Value(Line);
Line_Count := 1;
end;
end loop;
Ada.Text_IO.Close (File);
return ReturnSize;
end get_size;
begin
null;
end gear;
What I want to do is set my size
integer to the value returned by get_size
. How can I do this? I have tried putting my function before my size
variable in the spec file, but it expected end of file. I tried setting size : integer := gwar.get_size
, but that does not work either. Is this possible?
回答1:
Preferably considering manuBriot's remarks, I guess, you could still follow Simon Wright's suggestion technically. I have made a few omission to focus on how to assign a value to a generic parameter in the generic itself.
GENERIC
TYPE Item IS PRIVATE; --type of array
size : in out integer; --size of array
PACKAGE gwar IS
function get_size return integer;
END gwar;
with Ada.Text_Io;
use Ada.Text_Io;
package body gwar is
function get_size return Integer is
ReturnSize : Integer;
begin
ReturnSize := Integer'Value("2");
return ReturnSize;
end get_size;
begin
Size := Get_Size;
end gwar;
This way, when you instantiate the generic, the instance body's effect will be to set the parameter size
to the value 2
, provided that get_size
returns without error.
回答2:
As sent, the code looks strange. Here is a quick review of various inconsistencies:
the two formal parameters
Item
andSize
are not used in the implementation of the package. So likely you do not need a generic package here.Get_Size
is a function, and doesn't need to store the information anywhere (although the caller, in another package, might want to store it in a local variable of course). Better to have functions without side effects when possibleIn
Get_Size
, you have a loop that will only ever execute once, sinceLine_Count
is set to 1 always. There are better functions to compute the size of a file. If you need to count the number of lines, for instance, consider usingGNATCOLL.Mmap
to read the whole file in memory at once. That will be faster.You should likely handle exceptions, for instance in the case the file doesn't exist on the disk or is not readable.
Better have the documentation of
Get_Size
in the spec, than in the body, so that users of the package can see that documentation. The GPS editor, if that's what you are using, will display tooltips on all references toGet_Size
, and these tooltips include the documentation
回答3:
If all you want is to determine the size of a file you should look at the package Ada.Directories. Documentation for this package is found at section A.16 of the Ada Language Reference Manual. If you are using the GPS development environment you can access the Ada Language Reference Manual through the Help menu.
The Ada.Directories package contains a wealth of functions and procedures for manipulating and understanding files. For instance, the function Exists takes a file name as a parameter and returns a boolean indicating whether or not the named file exists. There is also a function Size which takes a file name as a parameter and returns the size of the file.
It makes sense to check if a file exists before trying to determine the size of the file.
来源:https://stackoverflow.com/questions/39585364/variable-initialization-in-generic-package-body-using-return-value-of-function