什么是神奇数字?
为什么要避免呢?
有没有合适的情况?
什么是神奇数字?
为什么要避免呢?
有没有合适的情况?
当前回答
我想这是在回答你之前的问题。在编程中,魔数是一个没有解释就出现的嵌入数字常数。如果它出现在两个不同的位置,则可能导致一个实例被更改而另一个实例未更改的情况。出于这两个原因,在使用数值常数的地方之外隔离和定义数值常数是很重要的。
其他回答
值得注意的是,有时您确实希望在代码中使用不可配置的“硬编码”数字。有许多著名的,包括0x5F3759DF,它用于优化的平方根反算法。
在极少数情况下,我发现需要使用这种神奇的数字,我将它们设置为我的代码中的const,并记录为什么使用它们,它们是如何工作的,以及它们来自哪里。
Magic Number是一个硬编码的值,它可能在以后的阶段更改,但因此很难更新。
例如,假设您有一个页面,在“您的订单”概览页面中显示最近50个订单。50在这里是一个神奇的数字,因为它不是通过标准或惯例设置的,它是您根据规范中概述的原因虚构的数字。
现在,你要做的是你在不同的地方有50个-你的SQL脚本(SELECT TOP 50 * FROM orders),你的网站(你的最后50个订单),你的订单登录(for (i = 0;I < 50;i++))和可能的许多其他地方。
那么,如果有人决定把50岁改成25岁,会发生什么呢?还是75年?还是153年?现在你必须在所有的地方替换50,你很可能会错过它。Find/Replace可能不起作用,因为50可能用于其他事情,盲目地将50替换为25可能会产生一些其他不良副作用(即你的Session)。Timeout = 50呼叫,也设置为25,用户开始报告太频繁的超时)。
此外,代码可能很难理解,即。"if a < 50那么bla"——如果你在一个复杂的函数中遇到这种情况,其他不熟悉代码的开发人员可能会问自己"WTF是50?? "
这就是为什么最好在1个地方有这样模糊和任意的数字-“const int NumOrdersToDisplay = 50”,因为这使代码更具可读性(“如果< NumOrdersToDisplay”,这也意味着你只需要在1个定义良好的地方更改它。
适用Magic Numbers的地方是通过标准定义的所有内容,即SmtpClient。DefaultPort = 25或TCPPacketSize =任何(不确定是否标准化)。此外,只在一个函数中定义的所有内容都可能是可接受的,但这取决于上下文。
在类的顶部用默认值初始化一个变量怎么样?例如:
public class SomeClass {
private int maxRows = 15000;
...
// Inside another method
for (int i = 0; i < maxRows; i++) {
// Do something
}
public void setMaxRows(int maxRows) {
this.maxRows = maxRows;
}
public int getMaxRows() {
return this.maxRows;
}
在这种情况下,15000是一个神奇的数字(根据CheckStyles)。对我来说,设置一个默认值是可以的。我不想做的事情是:
private static final int DEFAULT_MAX_ROWS = 15000;
private int maxRows = DEFAULT_MAX_ROWS;
这会让它更难读吗?在安装CheckStyles之前,我从未考虑过这一点。
你看过维基百科上关于魔法数字的词条了吗?
它详细介绍了魔术数字引用的所有方式。下面是关于魔术数字是一种糟糕的编程实践的引用
“魔数”一词也指在源代码中直接使用数字而不作解释的糟糕编程实践。在大多数情况下,这会使程序更难阅读、理解和维护。尽管大多数指南对数字0和1做了例外处理,但在代码中将所有其他数字定义为命名常量是个好主意。
幻数是文件格式或协议交换开头的字符序列。这个数字可以作为一个完整性检查。
例子: 打开任何GIF文件,你会在最开始看到:GIF89。GIF89是一个神奇的数字。
其他程序可以读取文件的前几个字符,并正确识别gif。
危险在于随机二进制数据可能包含这些相同的字符。但这种可能性非常小。
至于协议交换,您可以使用它来快速识别正在传递给您的当前“消息”是否已损坏或无效。
神奇的数字仍然很有用。