pol*_*nts 12 java magic-numbers
可能重复:
持续滥用?
我已经看到-1在各种API中使用,最常见的是搜索具有从零开始的索引的"集合"时,通常用于指示"未找到"索引.这"有效",因为-1从来不是一个合法的索引.似乎任何负数都应该有效,但我认为-1几乎总是使用某种(不成文的?)约定.
我想至少暂时将范围限制为Java.我的问题是:
-1像这样的"特殊"返回值,Sun的官方文字是什么?mdm*_*dma 11
这是一种常见的语言,其中的类型不包括范围检查."越界"值用于表示几种情况之一.这里,返回值表示两件事:1)是找到的字符,2)它在哪里找到.使用-1 for not found和非负索引found将这两者简洁地编码为一个值,以及not-found不需要返回索引的事实.
在具有严格范围检查的语言中,例如Ada或Pascal,该方法可以实现为(伪代码)
bool indexOf(c:char, position:out Positive);
Run Code Online (Sandbox Code Playgroud)
Positive 是int的子类型,但仅限于非负值.
这将找到/未找到的标志与位置分开.该位置作为输出参数提供 - 基本上是另一个返回值.它也可以是一个输入输出参数,从给定位置开始搜索.这里不允许使用-1表示not-found,因为它违反了Positive类型的范围检查.
java中的替代方案是:
boolean indexOf(char c); int lastFoundIndex();.这意味着对象必须保持状态,这在并发程序中不起作用,除非状态存储在线程本地存储中,或者使用同步 - 所有相当大的开销.boolean indexOf(char c, Position pos).这里,创建位置对象可能被视为不必要的开销.如
class FindIndex {
boolean found;
int position;
}
FindIndex indexOf(char c);
Run Code Online (Sandbox Code Playgroud)
虽然它明确地区分了返回值,但它会受到对象创建开销的影响.其中一些可以通过传递FindIndex作为参数来减轻,例如
FindIndex indexOf(char c, FindIndex start);
Run Code Online (Sandbox Code Playgroud)
顺便提一下,多个返回值将成为java(oak)的一部分,但是在1.0之前被削减以缩短发布时间.詹姆斯戈斯林说他希望他们被包括在内.它仍然是一个希望的功能.
我的看法是使用魔术值是在单个返回值中编码多值结果(标志和值)的实用方法,而不需要过多的对象创建开销.
但是,如果使用魔术值,如果它们在相关的api调用中保持一致,则使用它会更好.例如,
// get everything after the first c
int index = str.indexOf('c');
String afterC = str.substring(index);
Run Code Online (Sandbox Code Playgroud)
Java在这里不足,因为在调用中使用-1 substring会导致IndeOutOfBoundsException.相反,如果将负值视为在字符串末尾开始,则在使用-1调用时,子字符串返回""可能更加一致.对错误条件的魔术值的批评者说,可以忽略返回值(或假设为正数).以有用的方式处理这些魔术值的一致api将减少检查-1并允许更清晰的代码的需要.