今天我确实在D邮件列表中询问是否可以以类似于例如的方式定义和使用自定义数据类型。例如Ada的wiki页面:
type Day_type is range 1 .. 31;
type Month_type is range 1 .. 12;
type Year_type is range 1800 .. 2100;
type Hours is mod 24;
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
type Date is
record
Day : Day_type;
Month : Month_type;
Year : Year_type;
end record;
subtype Working_Hours is Hours range 0 .. 12;
subtype Working_Day is Weekday range Monday .. Friday;
Work_Load: constant array(Working_Day) of Working_Hours
:= (Friday => 6, Monday => 4, others => 10);
并且reply展示了类似的内容:
import std.typecons;
import std.exception;
struct Limited(T, T lower, T upper)
{
T _t;
mixin Proxy!_t; //Limited acts as T (almost)
invariant()
{
enforce(_t >= lower && _t <= upper);
}
this(T t)
{
_t = t;
}
}
auto limited(T, T lower, T upper)(T init = T.init)
{
return Limited!(T, lower, upper)(init);
}
unittest
{
enum l = [-4,9];
auto a = limited!(int, l[0], l[1])();
foreach(i; l[0] .. l[1]+1)
{
a = i;
}
assertThrown({a = -5;}());
assertThrown({a = 10;}());
}
表明这是可能的,但可能会错过Ada的优雅。
现在,在最近阅读了关于Nimrod之后,我想知道如何处理类似的任务以确保相同的Ada的类型安全吗?
答案 0 :(得分:7)
Nimrod直接支持这些:
type
Day = range[1..31]
Month = range[1..12]
WeekDay = enum
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
WorkingDays = range[Monday..Friday]
WorkingHours = range[0..12]
WorkSchedule = array[WorkingDays, WorkingHours]
错误在编译时强制执行:
var x: Day
x = 40 # conversion from int literal(40) to Day is invalid
..或在运行时
var x: Day
var y = unknownInt() # let's say it returns 100
x = y # unhandled exception: value 100 out of range [EOutOfRange]
此外,如果需要更强的类型安全性,可以使用distinct types。
答案 1 :(得分:0)
此外,实例化使用
变得更简单import std.traits;
/*! Instantiator for \c Limited. */
template limited(alias min, alias max, bool Exceptional = true)
if (!is(CommonType!(typeof(min), typeof(max)) == void)) {
auto limited(CommonType!(typeof(min), typeof(max)) value) {
return Limited!(typeof(value), min, max)(value);
}
}