什么是神奇数字?
为什么要避免呢?
有没有合适的情况?
什么是神奇数字?
为什么要避免呢?
有没有合适的情况?
当前回答
关于使用神奇数字,还有一个问题没有被提及……
如果你有很多这样的数字,很有可能你有两个不同的目的,你使用魔法数字,其中的值碰巧是相同的。
然后,果然,你需要改变值…只有一个目的。
其他回答
我总是以不同的方式使用术语“魔数”,作为存储在数据结构中的模糊值,可以作为快速有效性检查进行验证。例如,gzip文件的前三个字节包含0x1f8b08, Java类文件以0xcafebabe开头,等等。
您经常看到在文件格式中嵌入了神奇的数字,因为文件可以相当混乱地四处发送,并丢失关于它们如何创建的任何元数据。然而,魔法数字有时也用于内存中的数据结构,如ioctl()调用。
在处理文件或数据结构之前快速检查这个神奇的数字,可以尽早发现错误,而不是为了宣布输入完全是胡编乱作而进行可能很长的处理。
魔术数字是在代码中直接使用数字。
例如,如果你有(在Java中):
public class Foo {
public void setPassword(String password) {
// don't do this
if (password.length() > 7) {
throw new InvalidArgumentException("password");
}
}
}
这应该被重构为:
public class Foo {
public static final int MAX_PASSWORD_SIZE = 7;
public void setPassword(String password) {
if (password.length() > MAX_PASSWORD_SIZE) {
throw new InvalidArgumentException("password");
}
}
}
它提高了代码的可读性,也更容易维护。想象一下我在GUI中设置密码字段大小的情况。如果我使用一个神奇的数字,每当最大大小发生变化时,我必须在两个代码位置进行更改。如果我忘记了一个,就会导致不一致。
JDK中有很多例子,比如Integer, Character和Math类。
PS:像FindBugs和PMD这样的静态分析工具可以检测到代码中使用的神奇数字,并建议进行重构。
关于使用神奇数字,还有一个问题没有被提及……
如果你有很多这样的数字,很有可能你有两个不同的目的,你使用魔法数字,其中的值碰巧是相同的。
然后,果然,你需要改变值…只有一个目的。
值得注意的是,有时您确实希望在代码中使用不可配置的“硬编码”数字。有许多著名的,包括0x5F3759DF,它用于优化的平方根反算法。
在极少数情况下,我发现需要使用这种神奇的数字,我将它们设置为我的代码中的const,并记录为什么使用它们,它们是如何工作的,以及它们来自哪里。
@eed3si9n:我甚至认为“1”是一个神奇的数字。: -)
与神奇数字相关的一个原则是,代码处理的每个事实都应该声明一次。如果您在代码中使用神奇的数字(例如@marcio给出的密码长度示例),那么您很容易复制该事实,当您对事实的理解发生变化时,您就会遇到维护问题。