什么是神奇数字?
为什么要避免呢?
有没有合适的情况?
什么是神奇数字?
为什么要避免呢?
有没有合适的情况?
当前回答
我总是以不同的方式使用术语“魔数”,作为存储在数据结构中的模糊值,可以作为快速有效性检查进行验证。例如,gzip文件的前三个字节包含0x1f8b08, Java类文件以0xcafebabe开头,等等。
您经常看到在文件格式中嵌入了神奇的数字,因为文件可以相当混乱地四处发送,并丢失关于它们如何创建的任何元数据。然而,魔法数字有时也用于内存中的数据结构,如ioctl()调用。
在处理文件或数据结构之前快速检查这个神奇的数字,可以尽早发现错误,而不是为了宣布输入完全是胡编乱作而进行可能很长的处理。
其他回答
那么返回变量呢?
我发现在实现存储过程时尤其具有挑战性。
想象下一个存储过程(我知道语法错误,只是举个例子):
int procGetIdCompanyByName(string companyName);
如果该公司存在于特定的表中,则返回该公司的Id。否则,返回-1。 不知何故,这是一个神奇的数字。到目前为止,我读到的一些建议说,我真的必须设计这样的东西:
int procGetIdCompanyByName(string companyName, bool existsCompany);
顺便问一下,如果公司不存在,它应该返回什么?它会将existesCompany设为false,但也会返回-1。
Antoher的选择是做两个独立的功能
bool procCompanyExists(string companyName);
int procGetIdCompanyByName(string companyName);
因此第二个存储过程的先决条件是公司存在。
但是我害怕并发,因为在这个系统中,一个公司可以由另一个用户创建。
顺便说一句,最重要的是:你对使用这种相对已知和安全的“神奇数字”来判断某事不成功或某事不存在有什么看法?
魔术数字也可以是具有特殊的硬编码语义的数字。例如,我曾经看到一个系统,其中记录id > 0被正常对待,0本身是“新记录”,-1是“这是根”,-99是“这是在根中创建的”。0和-99将导致WebService提供一个新的ID。
这样做的不好之处在于,您重用了用于特殊功能的空间(记录id的有符号整数的空间)。也许您永远不希望创建ID为0或ID为负的记录,但即使不是这样,每个查看代码或数据库的人都可能在一开始无意中发现这一点并感到困惑。不用说,这些特殊的值并没有得到很好的记录。
可以说,22、7、-12和620也可以算作神奇数字。: -)
关于使用神奇数字,还有一个问题没有被提及……
如果你有很多这样的数字,很有可能你有两个不同的目的,你使用魔法数字,其中的值碰巧是相同的。
然后,果然,你需要改变值…只有一个目的。
值得注意的是,有时您确实希望在代码中使用不可配置的“硬编码”数字。有许多著名的,包括0x5F3759DF,它用于优化的平方根反算法。
在极少数情况下,我发现需要使用这种神奇的数字,我将它们设置为我的代码中的const,并记录为什么使用它们,它们是如何工作的,以及它们来自哪里。
幻数是文件格式或协议交换开头的字符序列。这个数字可以作为一个完整性检查。
例子: 打开任何GIF文件,你会在最开始看到:GIF89。GIF89是一个神奇的数字。
其他程序可以读取文件的前几个字符,并正确识别gif。
危险在于随机二进制数据可能包含这些相同的字符。但这种可能性非常小。
至于协议交换,您可以使用它来快速识别正在传递给您的当前“消息”是否已损坏或无效。
神奇的数字仍然很有用。