如何实现基于Modular Type索引的数组切片自动环绕访问?
Ada模块化索引数组的环绕切片实现
你需要实现的数组切片逻辑:
- 若结束索引在数组范围内(大于等于起始索引),按常规切片访问
- 若结束索引小于起始索引,自动拼接
First .. A'Last与A'First .. 结束索引的切片,实现环绕访问
你的测试代码尝试直接用A(First .. First + 5)实现,但因为Ada的模块化索引切片在结束索引小于起始索引时会生成空切片,导致编译器警告循环范围为空,运行无输出:
with Ada.Text_IO; use Ada.Text_IO; procedure Test_Modular is type Idx is mod 10; type My_Array is array (Idx range <>) of Integer; A: My_Array(Idx) := ( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9 ); First: constant Idx := 7; S: constant My_Array := A(First .. First + 5); begin for I in S'range loop Put_Line(Idx'Image(I) & " --> " & Integer'Image(S(I))); end loop; end Test_Modular;
编译时的警告:
$ gnatmake -o test_modular test_modular.adb x86_64-linux-gnu-gcc-10 -c test_modular.adb test_modular.adb:18:19: warning: loop range is null, loop will not execute x86_64-linux-gnu-gnatbind-10 -x test_modular.ali x86_64-linux-gnu-gnatlink-10 test_modular.ali -o test_modular
解决方案:自定义封装函数
Ada原生切片语法不支持自动环绕,但可以通过自定义一个Slice函数封装逻辑,让调用方式接近你想要的简洁写法,无需显式区分两种情况:
with Ada.Text_IO; use Ada.Text_IO; procedure Test_Modular_Slice is type Idx is mod 10; type My_Array is array (Idx range <>) of Integer; -- 自定义环绕切片函数 function Slice(Arr : My_Array; Start, Stop : Idx) return My_Array is begin if Stop >= Start then return Arr(Start .. Stop); else return Arr(Start .. Arr'Last) & Arr(Arr'First .. Stop); end if; end Slice; A: My_Array(Idx) := ( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9 ); First: constant Idx := 7; -- 使用自定义Slice函数,写法接近你想要的形式 S: constant My_Array := Slice(A, First, First + 5); begin for I in S'range loop Put_Line(Idx'Image(I) & " --> " & Integer'Image(S(I))); end loop; end Test_Modular_Slice;
运行效果
这段代码会输出:
7 --> 7 8 --> 8 9 --> 9 0 --> 0 1 --> 1 2 --> 2
完全等同于你手动拼接两个切片的效果,而且调用时只需要一行代码,无需显式判断索引范围。
逻辑说明
- 函数
Slice首先判断结束索引Stop是否大于等于起始索引Start:- 是则直接返回常规切片
Arr(Start .. Stop) - 否则拼接从
Start到数组末尾,以及从数组开头到Stop的两个切片,实现环绕效果
- 是则直接返回常规切片
- 因为
Idx是模块化类型,First +5会自动做模运算(7+5=12 mod10=2),无需额外处理
内容的提问来源于stack exchange,提问作者linux-fan
相关产品推荐
相关产品推荐

