为什么Java,C#和C ++没有范围?

Ada , Pascal和许多其他语言支持范围,一种子类型整数的方法。 范围是有符号整数值,其范围从值(第一个)到另一个(最后一个)。 在OOP中实现相同的类很容易,但我认为本机支持该function可以让编译器进行额外的静态检查。

我知道静态validation一个范围内定义的变量不会“溢出”运行时,即由于输入错误,我无法进行validation,但我认为可以做一些事情。 我想到了契约式设计方法(Eiffel)和Spec#( C#契约 ),它们提供了更为通用的解决方案。

是否有一个更简单的解决方案,至少在C ++,C#和Java的编译时检查静态的越界分配? 某种静态断言 ?

编辑 :我知道“范围”可以用于不同的目的:

  1. 迭代器
  2. 统计员
  3. 整数子类型

我会专注于后者,因为前者很容易在C *语言上映射。 我想到一组封闭的值,比如音乐音量,即从1到100的范围。我想用一个值递增或递减它。 我希望在静态溢出的情况下出现编译错误,例如:

volume=rangeInt(0,100); volume=101; // compile error! volume=getIntFromInput(); // possible runtime exception 

谢谢。

子范围类型在实践中实际上并不是非常有用。 我们不经常分配固定长度数组,也没有理由使用固定大小的整数。 通常我们看到固定大小的数组,它们作为枚举,我们有一个更好的(虽然“更重”)解决方案。

子范围类型也使类型系统复杂化。 在变量之间引入约束比固定常数更有用。

(强制性地提到整数应该是任意合理语言的任意大小。)

Java从版本1.4开始就有一个断言关键字。 如果您按合同进行编程,则可以自由地使用这些来检查正确的分配。 并且应该在设置之前检查对象内应该落在某个范围内的任何可变属性。 您还可以抛出IllegalArgumentException。

为什么没有范围类型? 我的猜测是,原始设计师没有在C ++中看到它,并且认为它不像其他function那样重要。

简洁地说,当你可以在这个范围内做某些事情时,范围是最有用的。 这意味着关闭。 至少对于Java和C ++,与迭代器相比,范围类型会很烦人,因为您需要定义一个内部类来定义您将在该范围内执行的操作。

Pascal(以及Delphi)使用子范围类型,但它仅限于序数类型(整数,字符和偶数布尔值)。

它是一个带有额外类型检查的整数。 您可以使用类来伪造其他语言。 这样可以使您可以应用更复杂的范围。

对于C ++,目前正在实现受约束值变量的lib,并将在boost库中提出: http : //student.agh.edu.pl/~kawulak/constrained_value/index.html

在C#中你可以这样做:

 foreach(int i in System.Linq.Enumerable.Range(0, 10)) { // Do something } 

C ++允许您通过模板实现这些类型,我认为已经有一些库可用。 但是,我认为在大多数情况下,其好处太小,不足以certificate增加的复杂性和编译速度的损失。

至于静态断言,它已经存在。 Boost有一个BOOST_STATIC_ASSERT ,在Windows上,我认为微软的ATL库定义了一个类似的。

boost::type_traits和boost :: mpl可能是你实现这样的东西的最好朋友。

滚动自己的灵活性比将其内置到语言中更好。 例如,如果您想要饱和算术,而不是为超出范围的值抛出exception,该怎么办? 即

 MyRange<0,100> volume = 99; volume += 10; // results in volume==100 

我想补充Tom Hawtin的回应(我同意),对于C ++,范围的存在并不意味着它们会被检查 – 如果你想要与一般的语言行为保持一致 – 例如,数组访问是无论如何也没有范围检查。 对于C#和Java,我认为决定是基于性能 – 检查范围会增加负担并使编译器复杂化。

请注意,范围在调试阶段主要是有用的 – 在生产代码中(理论上)不应发生范围违规。 因此,范围检查最好不是在语言本身内部实现,而是在前后条件下实现,在生成发布版本时可以(应该)将其删除。

这是一个老问题,但只是想更新它。 Java本身没有范围,但是如果你真的想要这个函数,可以使用Commons Lang ,它有很多范围类,包括IntRange

 IntRange ir = new IntRange(1, 10); 

奇怪的是,这在Commons Math中并不存在。 我部分同意接受的答案,但我不认为范围是无用的,特别是在测试用例中。

JSR-305为范围提供了一些支持,但我不知道它何时会成为Java的一部分。