这是我在本网站上的第一个问题。我总是设法找到一些与我有类似问题的人回答的问题,但这次似乎没有。
所以在这里,我试图生成大量相对较短的字符串作为ID号,但希望它们只包含字母数字字符。
我尝试了一些类似的事情:
subtype Char is character range 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9';
添加括号,逗号,创建新类型而不是子类型。
我知道我可以枚举我想要的所有角色,但我可以让自己完成这样一个愚蠢的任务,就像在枚举类型中编写每个62个字符一样。
有没有办法将不同的区间连接成一个子类型?
编辑:所以这是我的代码:
with ada.text_io, ada.integer_text_io, ada.float_text_io, ada.numerics.discrete_random;
use ada.text_io, ada.integer_text_io, ada.float_text_io;
procedure randomID is
Subtype AlphaNumeric is character
with dynamic_predicate => AlphaNumeric in 'a'..'z' |
'A'..'Z' |
'1'..'9' ;
package CharGen is new ada.numerics.discrete_random (Alphanumeric);
CharG: CharGen.generator;
id: string (1..5);
begin
for i in 1..5 loop
CharGen.Reset(CharG);
id(i) := charGen.random(CharG);
end loop;
end randomID;
但我得到(无论我使用静态还是动态指示)这些错误:
09:警告:在a-nudira.adb的实例化中:54
09:警告:输入" Result_Subtype"有谓词,属性"第一"不允许的 09:警告:将在运行时提出Program_Error 09:警告:在a-nudira.adb的实例化中:54
09:警告:表达式未通过谓词检查" Result_Subtype"
09:警告:在s-rannum.ads:86实例化 09:警告:在a-nudira.adb的实例化中:53
09:警告:输入" Result_Subtype"有谓词,属性"最后"不允许的 09:警告:在s-rannum.adb的实例化中:395
09:警告:在a-nudira.adb的实例化中:53
09:警告:输入" Result_Subtype"有谓词,属性"最后"不允许
我理解Ada.numerics生成随机项目的方式与我的类型的性质存在冲突。有办法解决这个问题吗?
答案 0 :(得分:3)
你可以通过至少两种不同的方式来做到这一点。
使用静态谓词作为+-------------------+----+----+
|timestamp |1 |2 |
+-------------------+----+----+
|2017-11-01 05:33:00|5 |null|
|2017-11-01 05:32:00|4 |109 |
|2017-12-01 05:31:00|6 |111 |
|2016-12-01 05:30:00|5 |100 |
|2016-12-01 05:34:00|null|95 |
+-------------------+----+----+
的子类型:
Character
作为一种合适的类型:
subtype Alphanumeric_Character is Character
with Static_Predicate => Alphanumeric_Character in 'a' .. 'z' |
'A' .. 'Z' |
'0' .. '9';
答案 1 :(得分:1)
我终于决定是时候玩谓词了,早在2012年之前就已经了解了我认识的小阿达。
由于具有谓词的子类型覆盖在基础类型上,因此必须进行一些有趣的讨论,以保留基础类型,禁止内容和添加内容......
事实证明,某些谓词(例如'first, 'last, 'range
)是被禁止的,而您在a-nudira.adb
又名ada.numerics.discrete_random
中使用了这些谓词。有'first_valid, 'last_valid
形式的替换可以按预期工作,但不会'range
,这将允许数据类型中的漏洞。
其他一些像'pos, 'val, 'pred,'succ
这样的人生存但是他们引用了基础类型,所以AlphaNumeric'Pred('A')
是' @'而不是' 9'例如。这很不方便,但是......
谓词的本质不是提供一些处理数组寻址中的漏洞的神奇编程,而是允许按合同编程。
合同编程的本质是双方(来电者和被叫者,实例者和通用包)都必须遵守合同。
不幸的是,ada.numerics.discrete_random
并未遵守合同。有可能写一个替代品,但这将是一个比我们现在需要的更大的项目。 (OTOH,如果您正在使用Gnat Pro,您的支持合同可能会涵盖此类增强功能: - )
所以这是一个修改,使用了一个符合合同的包装函数random
......
with ada.text_io, ada.integer_text_io, ada.float_text_io,
ada.numerics.discrete_random;
use ada.text_io, ada.integer_text_io, ada.float_text_io;
procedure randomID is
pragma Assertion_Policy(Check);
Subtype AlphaNumeric is character
with dynamic_predicate => AlphaNumeric in 'a'..'z' |
'A'..'Z' |
'1'..'9' ;
package CharGen is new ada.numerics.discrete_random (character);
CharG: CharGen.generator;
id : string (1..5);
function random return AlphaNumeric is
ch : character;
begin
loop
ch := charGen.random(CharG);
exit when ch in AlphaNumeric;
end loop;
return ch;
end random;
begin
for i in 1..5 loop
CharGen.Reset(CharG); -- wait what? should be outside the loop
id(i) := random;
end loop;
put_line(id);
end randomID;
这是否比定义自己的枚举更好,我不能说。但是,该枚举的数组将与字符串不兼容,因此如果您走这条路,您还可以使用其他形式的包装器进行编写。我遇到了这个问题,只需要id
array (1 .. 5) of AlphaNumeric
,这样可以确保调用者也执行合同。
答案 2 :(得分:0)
procedure randomID is
Type Table is array (1..62) of character;
AlphaNumeric : Table := ('a','b','c'...'7','8','9');
Type Int is new integer range 1..62;
package intGen is new ada.numerics.discrete_random (Int);
intG: IntGen.generator;
id: string (1..5);
begin
for i in 1..5 loop
intGen.Reset(intG);
id(i) := Alphanumeric(integer(intGen.Random(intG)));
end loop;
end randomID;