简体   繁体   中英

What type has a variable containing a range to be?

A for loop can be done in Ada using a range with a start and an end point:

for I in 0..10 loop
(...)
end loop;

I know, it's possible doing the for loop using two variables describing the range:

for I in range_start..range_end loop
(...)
end loop;

Is it also possible to store the range in one variable?, like:

for I in my_range loop
(...)
end loop;

Which type has the variable *my_range* to be?

Edit: Let's say I want to use this variable as a parameter in a subprogram: So the subprogram has this loop which iterates over the range. I'd rather use two variables describing the range instead of using generics, because generics would cause in higher effort. But I think using one variable describing the range would cause in a higher readability, that's why I'm asking that question.

If your variable is an array, then you can iterate over its range via:

for I in Arr_Var'Range loop
   ...
end loop;

If you're interested in iterating over the elements of a container, eg array, vector, map, etc., and don't care about the index, you can use generalized looping (Ada 2012 only):

for Elem of Container loop
   ...
end loop;

Use a range type, something along these lines:

type Range_Type is range -5 .. 10;
...
for A in Range_Type loop

See the complete example in here .

Hmmm. It looks like you may be (perhaps unknowingly) a devotee of Andrei Alexandrescu . He's argued strongly for languages to make ranges a first-class type, and the removal of "iterators" as a programming paradigm.

It would be interesting to see what an Ada implementation of this would look like. Unless I'm missing something, that's not the way Ada 2012 went.

If you want to pass around an object containing the range, you can wrap Start and End in a record. Inside the subprogram you can locally declare a new [sub]type bounded by the range.

type Range_Type is range TheRange.Start .. TheRange.end;

My count says you need 4 more lines to create a generic subprogram than a plain one:

generic                             -- extra
   type Bounds is (<>);             -- extra
procedure R;

procedure R is
begin
   for J in Bounds'Range loop
      null;
   end loop;
end R;

with R;
procedure P is
   type Rng is range 1 .. 10;       -- extra
   procedure A is new R (Rng);      -- extra
begin
   A;
end P;

which doesn't seem so bad.

But, usually an iteration is iterating over something (an array, ...): if so, you can derive the iteration range from the thing that's being iterated over.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM