Nimrod中类似Ada的类型

10

今天我在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相同的类型安全性?

2个回答

7
尼姆罗很直接地支持这些功能:
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]

此外,如果需要更强的类型安全性,则可以使用不同的数据类型。 请参考链接

谢谢。Araq也在#ada上发布了一些内容,我们进行了一些讨论。我之前不知道Nimrod可以像Ada一样优雅地完成任务,这让我很高兴,但是我认为缺乏GUI绑定将使我坚持使用Ada。 - gour
嗯,Ada并不是以其图形绑定而闻名。(尽管我发现这个,表明有一些好的/易于使用的现有包存在。)但是,希望能够对事情进行一些纠正,并会出现一个好的、开放的、平台无关的GUI包。(我不认为仅有绑定就足够资格。) - Shark8

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);
    }
}

查看绑定模板的实例化函数无法编译


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接