Ada / Gnat-包级动态泛型实例化

时间:2018-08-13 23:59:40

标签: generics packages instantiation ada gnat

我有一个通用包装:

generic
    Size : Positive;
package Foo is

    type Unbounded_Sized_Array is Array(1..Size) of Unbounded_String;

    type My_Type is
    record
        My_Array : Unbounded_Sized_Array;
        --other stuff
    end record;

end Foo;

我需要在另一个包中的包级别上声明它:

package Bar is

    package Dynamic_Foo is new Foo(Count);

    --other stuff

end Bar;

问题是我不知道什么是Count,直到执行完一些代码之后(这是给定目录中文件的数量),而且我不确定如何才能将Dynamic_Foo的实例化推迟到完成之后。甚至可以在Ada中完成。我可以创建一个链表类型,但是我真的不愿意,因为大小/长度在启动后应该保持不变。

3 个答案:

答案 0 :(得分:5)

您可以在任何声明性区域中声明新类型并实例化泛型,因此只需将实例化到Count具有正确值的位置即可。

您还可以使Count为一个函数,该函数返回所需的值。然后Count将在您实例化函数的地方调用,并且一切都会好起来(除了我在评论中提到的竞争条件)。

答案 1 :(得分:1)

例如:

with Ada.Text_IO; use Ada.Text_IO;
with Foo;

procedure Proc1 is
   Count : Positive := 5;
   package Foocounted1 is new Foo (Count);
   A : Foocounted1.Unbounded_Sized_Array;
begin
   Put_Line ("A'Length = " & Integer'Image (A'Length));
   Count := Count + 20;
   declare
      package Foocounted2 is new Foo (Count);
      B : Foocounted2.Unbounded_Sized_Array;
   begin
      Put_Line ("B'Length = " & Integer'Image (B'Length));
   end;
end Proc1;

答案 2 :(得分:1)

在我看来,您好像想要一个无界的Unbounded_String数组。在Ada中,无边界数组由名为的包提供,就像您期望的无约束数组pda Ada.Containers.Vectors:

for tbl_name in list_of_table_names:

    # Check if table exists by querying information tables
    def has_table(tbl_name=tbl_name):
        p = JdbcHook('conn_id')
        sql =""" select count(*) from system.tables where name = '{}' """.format(tbl_name.upper())
        count = p.get_records(sql)[0][0] #unpack the list/tuple

        # If the query didn't return rows, branch to Create Table Task
        # otherwise, branch to Dummy Operator (Airflow requires that both branches have a task)
        if count == 0:
            return 'tbl_create_{}'.format(tbl_name)
        else:
            return 'dummy_{}'.format(tbl_name) 

    # run has_table python function
    exists = BranchPythonOperator(
        task_id='tbl_exists_{}'.format(tbl_name),
        python_callable=has_table,
        depends_on_past=False,
        dag=dag
    )

    # Dummy Operator
    dummy = DummyOperator(task_id='dummy_{}'.format(tbl_name),dag=dag,depends_on_past=False)

    # Run create table SQL script
    create = JdbcOperator(
        task_id='tbl_create_{}'.format(tbl_name),
        jdbc_conn_id='conn_id',
        sql = sql_parse(script_path, 'sql/sql_create/{}.sql'.format(tbl_name)), 
        depends_on_past=False,
        dag = dag
    )

    # Run insert or truncate/replace SQL script
    upsert = JdbcOperator(
        task_id='tbl_upsert_{}'.format(tbl_name),
        jdbc_conn_id='conn_id',
        sql = sql_parse(script_path, 'sql/sql_upsert/{}.sql'.format(tbl_name)),
        trigger_rule=TriggerRule.ONE_SUCCESS,
        dag = dag
    )

    # Set dependencies
    exists >> create >> upsert 
    exists >> dummy >> upsert

这样,无需先计算文件数。