2013-04-06 2 views
1

Здравствуйте, я новичок в ada, и я пытаюсь создать какой-то неограниченный массив, и я не могу понять, как это сделать в ada.Ada unconstrained type

package data_puzzle is 
    type rotation is private; 
    type map(x_l,y_l,z_l : Natural) is private; 
    type valid_rotations is private; 
private 
    type rotation is array(1..3) of Natural; 
    type map(x_l,y_l,z_l : Natural) is record 
     struct : Structure(x_l,y_l,z_l); 
     rot : rotation; 
    end record; 

    type valid_rotations is array(1..24) of map; --how can I make this row work? 
end data_puzzle; 

структура выглядит следующим образом

type structure(x_l,y_l,z_l : Natural) is record 
    structure : xyz(1..x_l,1..y_l,1..z_l); 
    X : Natural := x_l; 
    Y : Natural := y_l; 
    Z : Natural := z_l; 
end record; 

В принципе у меня есть карта с поворотами и данных. Затем я хочу сохранить все разные вращения в списке размером 24. Единственное решение, которое у меня есть сейчас, это инициировать Тип valid_rotations - это массив (1..24) карты (x, y, z), тогда он работает. Но я не хочу так начинать, потому что я не знаю, какой размер будет в тот момент.

Cheers!

+1

Сложно предположить, что 'type structure' имеет компонент с именем' structure'! Кроме того, мне интересно, почему «структура типа» имеет компоненты 'X',' Y', 'Z', инициализированные значением соответствующего дискриминанта, когда вы можете просто получить доступ к дискриминанту? –

ответ

1

Хорошо, проблема в том, что тип map может быть разного размера - поэтому компилятор не может просто отложить необходимый объем памяти без дополнительной информации - поэтому решение должно создать какую-то косвенность, которая может быть элементом массива: у нас есть этот тип с Ada 83 , но с Ada 2005 и далее мы можем дополнительно ограничить типы доступа от нулевого.

-- I don't know what this is supposed to be; I'm assuming an array. 
type xyz is Array(Positive Range <>, Positive Range <>, Positive Range <>) 
    of Integer; 

type structure(x_l,y_l,z_l : Natural) is record 
structure : xyz(1..x_l,1..y_l,1..z_l); 
X : Natural := x_l; 
Y : Natural := y_l; 
Z : Natural := z_l; 
end record; 

package data_puzzle is 
type rotation is private; 
type map(x_l,y_l,z_l : Natural) is private; 
type valid_rotations is private; 

type map_handle is private; 
private 
type rotation is array(1..3) of Natural; 
type map(x_l,y_l,z_l : Natural) is record 
    struct : Structure(x_l,y_l,z_l); 
    rot : rotation; 
end record; 

-- Because the size of the record "map" can change 
-- depending on its discriminants, we cannot simply 
-- make some array -- we can however have an array 
-- of accesses (since we know their sizes at compile) 
-- and constrain these access-types to be non-null. 
type valid_rotations is array(1..24) of map_handle; 

-- Here it is: an access which cannot be null. 
type map_handle is Not Null Access Map; 

end data_puzzle; 

Кроме того, я бы удалить _1 из дискриминантах (X, Y, Z) выглядят нормально для меня.

+0

человек компилируется сейчас :)! И спасибо за описание. Большой <3! – user2253350

+0

Проблема с видимыми пользователем типами доступа заключается в том, что пользователь получает выделение и не забудьте освободить его после завершения (если только они не заботятся об утечке памяти). Может быть безопаснее использовать [Ada.Containers.Indefinite_Vectors] (http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-18-10.html). Кроме того, как написано, пользователь не может создать экземпляр 'data_puzzle.valid_rotations', потому что он не может увидеть, как его инициализировать (с 24 нетонами доступа к уже выделенным картам). Я бы не использовал здесь «не null»; это в частной части, по крайней мере, пользователь не может понять это неправильно! –

+0

Indefinite_Vectors - хорошее решение и очень применимо, но если бы я предложил его с места в карьер, он не стал бы решать проблему «почему». – Shark8