为什么 Java、C# 和 C 不这样做? 有范围吗?

发布于 2024-07-13 15:44:05 字数 1432 浏览 5 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

沉睡月亮 2024-07-20 15:44:05

子范围类型实际上在实践中并不是很有用。 我们不经常分配固定长度的数组,也没有理由使用固定大小的整数。 通常,当我们确实看到固定大小的数组时,它们充当枚举,并且我们对此有更好的(尽管“更重”)解决方案。

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

(必须提到的是,在任何合理的语言中整数都应该是任意大小。)

Subrange types are not actually very useful in practice. We do not often allocate fixed length arrays, and there is also no reason for fixed sized integers. Usually where we do see fixed sized arrays they are acting as an enumeration, and we have a better (although "heavier") solution to that.

Subrange types also complicate the type system. It would be much more useful to bring in constraints between variables than to fixed constants.

(Obligatory mention that integers should be arbitrary size in any sensible language.)

药祭#氼 2024-07-20 15:44:05

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

Ranges are most useful when you can do something over that range, concisely. That means closures. For Java and C++ at least, a range type would be annoying compared to an iterator because you'd need to define an inner class to define what you're going to do over that range.

眼眸里的快感 2024-07-20 15:44:05

Java 从 1.4 版本开始就有了一个 assert 关键字。 如果您按照合同进行编程,您可以自由地使用它们来检查正确的分配。 对象内任何应落在特定范围内的可变属性都应在设置之前进行检查。 您还可以抛出 IllegalArgumentException。

为什么没有范围类型? 我的猜测是,最初的设计者没有在 C++ 中看到这一功能,并且认为它不如他们试图正确实现的其他功能那么重要。

Java has had an assert keyword since version 1.4. If you're doing programming by contract, you're free to use those to check proper assignment. And any mutable attribute inside an object that should fall within a certain range should be checked prior to being set. You can also throw an IllegalArgumentException.

Why no range type? My guess is that the original designers didn't see one in C++ and didn't consider it as important as the other features they were trying to get right.

痴者 2024-07-20 15:44:05

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

For C++, a lib for constrained values variables is currently being implemented and will be proposed in the boost libraries : http://student.agh.edu.pl/~kawulak/constrained_value/index.html

柒七 2024-07-20 15:44:05

这是一个老问题,但只是想更新一下。 Java 本身没有范围,但如果您确实想要该功能,可以使用 Commons Lang,它具有许多范围类,包括 IntRange

IntRange ir = new IntRange(1, 10);

奇怪的是,这不存在于公共数学。 我部分同意已接受的答案,但我不认为范围是无用的,特别是在测试用例中。

This is an old question, but just wanted to update it. Java doesn't have ranges per-se, but if you really want the function you can use Commons Lang which has a number of range classes including IntRange:

IntRange ir = new IntRange(1, 10);

Bizarrely, this doesn't exist in Commons Math. I kind of agree with the accepted answer in part, but I don't believe ranges are useless, particularly in test cases.

神妖 2024-07-20 15:44:05

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

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

Pascal (and also Delphi) uses a subrange type but it is limited to ordinal types (integer, char and even boolean).

It is primarilly an integer with extra type checking. You can fake that in an other language using a class. This gives the advantage that you can apply more complex ranges.

与风相奔跑 2024-07-20 15:44:05

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

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

I would add to Tom Hawtin response (to which I agree) that, for C++, the existence of ranges would not imply they would be checked - if you want to be consistent to the general language behavior - as array accesses, for instance, are also not range-checked anyway.
For C# and Java, I believe the decision was based on performance - to check ranges would impose a burden and complicate the compiler.

Notice that ranges are mainly useful during the debugging phase - a range violation should never occur in production code (theoretically). So range checks are better to be implemented not inside the language itself, but in pre- and post- conditions, which can (should) be stripped out when producing the release build.

小耗子 2024-07-20 15:44:05

C++ 允许您通过模板实现此类类型,并且我认为已经有一些库可以执行此操作。 然而,我认为在大多数情况下,好处太小,不足以证明增加的复杂性和编译速度损失是合理的。

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

boost::type_traits 和 boost::mpl 可能是实现这样的事情时最好的朋友。

C++ allows you to implement such types through templates, and I think there are a few libraries available doing this already. However, I think in most cases, the benefit is too small to justify the added complexity and compilation speed penalty.

As for static assert, it already exists.
Boost has a BOOST_STATIC_ASSERT, and on Windows, I think Microsoft's ATL library defines a similar one.

boost::type_traits and boost::mpl are probably your best friends in implementing something like this.

断爱 2024-07-20 15:44:05

自行推出的灵活性比将其内置到语言中更好。 例如,如果您想要饱和算术,而不是抛出超出范围的异常,该怎么办? IE

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

The flexibility to roll your own is better than having it built into the language. What if you want saturating arithmetic for example, instead of throwing an exception for out of range values? I.e.

MyRange<0,100> volume = 99;
volume += 10; // results in volume==100
番薯 2024-07-20 15:44:05

在 C# 中你可以这样做:

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

In C# you can do this:

foreach(int i in System.Linq.Enumerable.Range(0, 10))
{
    // Do something
}
寒尘 2024-07-20 15:44:05

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

JSR-305 provides some support for ranges but I don't know when if ever this will be part of Java.

时间海 2024-07-20 15:44:05

当需要 8 个或更少的元素时,在 .NET 中实现此目的的一种方法是使用元组。

(元组也支持超过 8 个元素,但并不容易:它们必须使用 Tuple 构造函数,这不太容易分配或读取,尤其是如果正在寻找编译时边界检查。)

参考 https://learn.microsoft.com/en-us/dotnet/api/system.tuple?view=net-8.0

包含 3 个元素的示例,导致编译时错误而不是运行时错误- 边界异常:

var range = Tuple.Create(3, 2, 5);
// compile-time error for out-of-bounds - if you happen to miss the intellisense error!
range.Item4 = someNumber;

One way to accomplish this in .NET when 8 or less elements are needed is by using a Tuple.

(More than 8 elements are also supported by Tuples, but not easily: they must use the Tuple<T1,T2,T3,T4,T5,T6,T7,TRest> constructor, which is not as straightforward to assign or read, especially if looking for compile-time bounds checking.)

Ref https://learn.microsoft.com/en-us/dotnet/api/system.tuple?view=net-8.0

Example with 3 elements, causing compile-time error instead of run-time out-of-bounds exception:

var range = Tuple.Create(3, 2, 5);
// compile-time error for out-of-bounds - if you happen to miss the intellisense error!
range.Item4 = someNumber;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文