为什么不应该使用“匈牙利表示法”?


122

我知道匈牙利语指的是-提供有关变量,参数或类型的信息作为其名称的前缀。每个人似乎都在疯狂地反对它,即使在某些情况下,这似乎是一个好主意。如果我觉得正在传递有用的信息,为什么不把它放在可用的地方呢?

另请参阅:人们在现实世界中是否使用匈牙利命名约定?


Answers:


174

大多数人以错误的方式使用匈牙利表示法,并且得到错误的结果。

阅读Joel Spolsky撰写的这篇出色文章:使错误的代码看起来错误

简而言之,在匈牙利符号中用变量名type(字符串)(Systems Hungarian)作为前缀是不好的,因为它没有用。

匈牙利注释法,正如它的作者所希望的那样,您在变量名前加上变量名kind(使用乔尔的示例:安全字符串或不安全字符串),因此所谓的Apps Hungarian具有其用途,并且仍然很有价值。


5
好的链接,对链接背后的内容有很好的总结,没有狂热。优秀的。
垃圾工

12
请注意,Joels示例在VBScript中,该语言长期以来没有用户定义的类。在OO语言中,您只需创建一个HtmlEncodedString类型并让Write方法仅接受该类型。“匈牙利语应用程序”仅在没有用户定义类型的语言中有用。
JacquesB

4
微软因过去滥用匈牙利符号而闻名。将类型信息附加到标识符不仅无用,而且实际上可能有害。首先,可读性较差。其次,在支持多态性或鸭式打字的语言中,传递了错误的信息。
威尔海姆特尔

9
如果我使用较旧的IDE进行直接C开发,我仍然喜欢使用匈牙利表示法...这样我知道没有类型转换问题。
哔哔

3
@Krumia:通常可以通过首先使用描述性变量名来防止这种情况。但是如果您想确定的话,为长度,权重等创建不同的类型(例如结构)并使用运算符重载来确保仅可能进行有效的操作会更加安全。
JacquesB 2014年

277

使用匈牙利语注释vmake使ncode难以理解。


101
打个比方,虽然有点不公平。比较:使用adjHungarian nNotation vMakes nReading nCode adjDifficult。
克里斯·诺

27
在那句话中,“使用”和“阅读”都是动名词。但是我明白你的意思了……
黑猩猩

28
@chimp:这使事情变得更加明显。既然您发现类型有误,是要重命名所有引用还是将它们保留为原样,从而提供错误信息?你输了。但这当然是应用匈牙利表示法的错误方式。
wilhelmtell

1
@Chris Noe:对于某些阅读方式(解析前缀和后缀,中间略看一眼),您的示例只会使情况变得更糟。我看到“正在使用”并听到“在说”。
鲍勃·克罗斯

3
@Jon:如果您的变量名不能完全放弃它所代表的含义,那么绝对应该将其重命名为更具描述性的名称(匈牙利表示法不是一个很大的改进)最好的情况是修复症状-无法解决问题)。
lov

104

乔尔错了,这就是原因。

他正在谈论的“应用程序”信息应该在类型系统中编码。您不应该依赖于翻转变量名来确保不会将不安全的数据传递给需要安全数据的函数。您应该将其设置为类型错误,这样就不可能这样做。任何不安全的数据都应具有标记为“不安全”的类型,以便根本无法将其传递给安全功能。要从不安全状态转换为安全状态,应要求使用某种消毒功能进行处理。

乔尔所说的“种类”很多东西都不是种类。实际上,它们是类型。

但是,大多数语言所缺乏的是一种类型表达系统,足以表现出这种区别。例如,如果C具有一种“强typedef”(typedef名称具有基本类型的所有操作,但不能转换为基本类型),那么很多这些问题就会消失。例如,如果您可以说strong typedef std::string unsafe_string;要引入一种unsafe_string无法转换为std :: string 的新类型(因此可能会参与重载解析等),那么我们就不需要傻前缀了。

因此,关于匈牙利语适用于非类型事物的中心说法是错误的。它用于类型信息。当然,类型信息比传统的C类型信息更丰富;类型信息对某种语义细节进行编码,以指示对象的用途。但是它仍然是类型信息,正确的解决方案始终是将其编码为类型系统。将其编码到类型系统中是获得适当验证和执行规则的最佳方法。变量名称根本不会榨菜。

换句话说,目标不应是“使错误的代码对开发人员来说看起来是错误的”。应该是“使错误的代码对编译器来说是错误 ”。


30
变量的意图应在变量的类型内进行编码,而不要像frigging命名方案那样易碎。
DrPizza

3
我也想使它成为编译器/解释器的工作,但这将为动态语言(Python,Ruby,PHP或Javascript)带来巨大的开销。
太多的PHP

22
“然而,大多数语言缺乏一种足以表现出这种区别的类型系统”。这就是问题所在。AppsHungarian是一种实用的方法,当以明显的方式使用这些语言以使程序员查看代码(而不是检查错误报告)时,可以突出显示问题。
尼尔·特罗登

6
@DrPizza:我相信您在提倡“ Apps匈牙利语”时错过了Joel提出的非常重要的观点之一:这种表示方式只是一个非常务实的权衡。使编译器能够看到“错误的代码”是一个伟大的目标,但是否总值得付出代价?
Yarik 2011年

4
@DrPizza:Joel is wrongWhat most languages lack, however, is a type system that's expressive enough to enforce these kind of distinctions.那么,既然大多数语言缺乏足够的表现来执行这些类型的区别,乔尔正确的。对?
sampathsris 2014年

46

我认为它会使源代码变得混乱不堪。

使用强类型语言也不会给您带来多少好处。如果您进行任何形式的类型不匹配伪造,编译器都会告诉您。


哇。15分钟内达到90个代表。好决定。
垃圾工

2
如果将它用作类型,是的,它没有用。传递其他信息很有用。
Lou Franco

12
@Lou,恰好-个人而言,我将修订历史记录存储在变量名中:字符串firstName_wasName_wasNameID_wasSweetCupinCakes
Shog9

@nsanders:尝试使用编译器检查两个变量类型均为整数时是否使用了相同的度量单位。
伊戈尔·莱维基

1
@ Shog9:我认为您不了解Apps匈牙利语表示法。它更多地是关于sFirstName与unFirstName(安全与不安全,未消毒)的关系,这样您就可以了解更多信息。仍然我认为在静态语言中,最好将String子类型化为UnsafeString和SafeString并仅允许SafeString输出。约定还可以,但是(通常)编译执行会更好。
2013年

28

匈牙利语表示法仅在没有用户定义类型的语言中才有意义。在现代的功能或OO语言中,您将有关值的“种类”的信息编码为数据类型或类,而不是变量名。

几个答案参考Joels的文章。但是请注意,他的示例在VBScript中,它不支持用户定义的类(至少很长一段时间)。在具有用户定义类型的语言中,您可以通过创建HtmlEncodedString-type然后让Write方法仅接受它来解决相同的问题。在静态类型的语言中,编译器将捕获任何编码错误,在动态类型的语言中,您将获得运行时异常-但​​是在任何情况下,都可以防止编写未编码的字符串。匈牙利语表示法只是将程序员转变为人工类型检查器,而这种工作通常可以由软件更好地处理。

Joel区分“系统匈牙利语”和“应用程序匈牙利语”,其中“系统匈牙利语”编码int,float等内置类型,而“应用程序匈牙利语”编码“种类”,这是高级元信息关于机器类型之外的变量,您可以在OO或现代功能语言中创建用户定义的类型,因此在这种意义上,类型和“种类”之间没有区别-两者都可以由类型系统表示-和“应用”匈牙利与“系统”匈牙利一样多余。

因此,回答您的问题:系统匈牙利语仅在不安全,弱类型的语言中有用,例如,将浮点值分配给int变量将使系统崩溃。匈牙利符号是六十年代特别发明的,用于BCPL,这是一种非常底层的语言,根本不进行任何类型检查。我认为今天没有一种通用的语言存在这个问题,但是这种符号作为一种“ 货物崇拜”编程而存在

如果您使用的语言没有用户定义的类型(例如旧版VBScript或VB的早期版本),那么应用匈牙利语就有意义。也许还有Perl和PHP的早期版本。再次,在现代语言中使用它是纯粹的货物崇拜。

用任何其他语言,匈牙利人都是丑陋,多余和脆弱的。它重复了类型系统中已知的信息,因此您不应该重复自己。为变量使用描述性名称,以描述此特定类型实例的意图。使用类型系统对变量的“种类”或“类”进行不变式和元信息编码。类型。

Joels文章的总要点-使错误的代码看起来不正确-是一个很好的原则。但是,更好的防范错误的方法是-尽可能使编译器自动检测错误的代码。


具有用户定义类型的语言并不总是使使用类型代替“种类”成为现实。考虑来自Joel's Apps Hungarian的前缀“ c”,“ d”,“ ix”。您是否在每种现代语言中都使用自定义整数类型?我不这么认为。因为现代语言仍然没有内置的自定义整数类型来存储索引,计数和两个数字之间的差。只要我们仍在使用普通整数,Apps Hungarian将是非冗余且有用的。
Eldritch难题,2012年

27

我在所有项目中始终使用匈牙利表示法。当我处理100个不同的标识符名称时,我发现它真的很有帮助。

例如,当我调用一个需要字符串的函数时,我可以键入's'并点击control-space,我的IDE会准确地向我显示以's'为前缀的变量名。

另一个优点是,当我给u加上unsigned前缀而给i加上带符号的ints前缀时,我立即看到我在以潜在危险的方式混合有符号和无符号的地方。

我记不清多少次在庞大的75000行代码库中,由于将局部变量命名为与该类的现有成员变量相同而引起的错误(由我和其他人引起)。从那时起,我总是在成员前加上'm_'

这是口味和经验的问题。尝试之前请不要敲它。


1
当一段代码实际上处理签名时,将签名编码为变量名非常有用。用它作为对所有变量强制执行约定的借口就是恕我直言。
Plumenator 2012年

不过,您对成员变量有一个很好的认识。但是在像Python这样的语言中,您不得不用self / this对象来限定成员的资格。
Plumenator 2012年

这只是提高生产力的一个技巧。就像IDE自动完成一样。根本上没有什么邪恶的。我相信必须允许有经验的编码人员使用他们自己的样式。强迫任何人选择某种风格都是不好的。我现在是一个开发人员,但是我不会对与我合作的任何人强制执行样式,除非他们一开始缺乏一致的样式。
rep_movsd 2012年

因此,您正在使用命名约定来过滤变量,是吗?我必须同意,这有点聪明。:-)但是,我的连线方式,锚点(或过滤条件,如果您愿意)始终是我的语义。类型很少(除非语义)。我希望这是有道理的。TL; DR:我还是会坚持变量命名根据是什么,他们代表了比如何他们表示。
Plumenator

1
当时我赞成匈牙利语,因此我对此表示支持。现在我很后悔,永远也不会回过头来给变量
加上

22

您忘记了包括此信息的第一原因。与您无关,程序员。它与您离开公司后的2到3年内要读这本书的人有关。

是的,IDE将为您快速识别类型。但是,当您阅读大量的“业务规则”代码时,不必暂停每个变量来确定其类型是一件很不错的事情。当我看到像strUserID,intProduct或guiProductID,它使很多更容易'斜坡上升的时间。

我同意MS在某些命名约定方面走得太远-我将其归类为“太多了”。

只要您遵守命名约定,它们就是好东西。我已经经历了足够多的旧代码,使我不断地回头查看许多如此命名的变量的定义,以至于我推了“骆驼套”(在上一份工作中被称为)。现在,我从事的工作是使用VBScript编写成千上万行完全不加注释的经典ASP代码,这是一场噩梦,试图找出问题所在。


作为一个VIM(没有IDE,没有突出显示,没有任何类型的悬停用户),我根本不理解此参数。我自然地理解,一个名为name的变量是一个字符串,而一个名为i或count的变量是一个int。真的需要sName和iCount吗?到底有什么帮助?我认为您的产品ID示例是一个特例,也许就可以了。但是即使那样,保持一致并在各处使用整数或字符串表示产品ID还是更好的解决方案,不是吗?整个命名过程似乎很简单。
MrFox 2012年

6
这是为了保持一致性。是的,“名称”从本质上隐含着一个字符串。但是您会假设“ userid”是什么?GUID?串?整数?甚至“ acctno”之类的值也可能为42或“ 23X”。大多数代码中的文档都很少。该标准可以帮助维护程序员。
大卫

1
@David我完全同意您的回答-一目了然知道变量的意图也是我更喜欢加前缀的原因,尤其是在像JS这样的动态语言中。
Daniel Sokolowski

10

不需要在每个变量名的开头加上隐含的字符,这表明变量名本身不够描述性。无论如何,大多数语言在声明时都需要变量类型,因此信息已经可用。

还有在维护期间需要更改变量类型的情况。示例:如果声明为“ uint_16 u16foo”的变量需要变为64位无符号,则将发生以下两种情况之一:

  1. 您将仔细检查并更改每个变量的名称(确保不要用相同的名称命名任何不相关的变量),或者
  2. 只需更改类型而不更改名称,这只会造成混乱。

9

Joel Spolsky写了一篇很好的博客文章。 http://www.joelonsoftware.com/articles/Wrong.html 基本上可以归结为,当一个体面的IDE告诉您要键入变量时,如果您不记得了,就不会使您的代码难以阅读。另外,如果您对代码进行足够的分隔,则不必记住将变量声明为三页以上的内容。


9

这些天范围是否比键入更重要,例如

* l for local
* a for argument
* m for member
* g for global
* etc

使用现代的重构旧代码,搜索和替换符号的技术,因为您更改了符号的类型很乏味,因此编译器将捕获类型更改,但通常不会捕获对范围的不正确使用,明智的命名约定在这里有所帮助。


再说一次,代码可能不应该太依赖范围。:-)
Plumenator 2012年

8

没有理由不应该正确使用匈牙利符号。之所以不受欢迎,是因为人们长期反对使用匈牙利符号,特别是在Windows API中。

在糟糕的日子里,在没有类似于DOS的IDE之前(奇怪的是您没有足够的可用内存来在Windows下运行编译器,因此您的开发是在DOS上完成的),您没有得到任何帮助。将鼠标悬停在变量名上。(假设您有鼠标。)您需要处理的是事件回调函数,其中所有内容都以16位int(WORD)或32位int(LONG WORD)的形式传递给您。然后,您必须将这些参数转换为给定事件类型的适当类型。实际上,许多API实际上都是无类型的。

结果是,API的参数名称如下:

LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT uMsg,
                            WPARAM wParam,
                            LPARAM lParam);

请注意,名称wParam和lParam虽然很糟糕,但实际上并不比命名它们为param1和param2更糟。

更糟糕的是,Window 3.0 / 3.1具有两种类型的指针,near和far。因此,例如,内存管理功能LocalLock的返回值是PVOID,而GlobalLock的返回值是LPVOID(长时间带有“ L”)。那可怕的符号,然后得到了扩展,从而一p ointer字符串是前缀LP,它从一切只是malloc分配的字符串区分。

反对这种事情也就不足为奇了。


6

匈牙利语表示法在不进行编译时类型检查的语言中很有用,因为它使开发人员可以快速提醒自己如何使用特定变量。它对性能或行为没有任何作用。它应该提高代码的可读性,并且主要是一种品味和编码风格。因此,许多开发人员都批评它-并非每个人的大脑都有相同的连线。

对于编译时的类型检查语言,它几乎是没有用的-向上滚动几行应该显示该声明并因此进行输入。如果全局变量或代码块跨越多个屏幕,那么您将面临严重的设计和可重用性问题。因此,批评之一是匈牙利符号法使开发人员的设计不好,并容易摆脱它。这可能是仇恨的原因之一。

另一方面,在某些情况下,甚至编译时类型检查语言也会受益于匈牙利符号-win32 API中的void指针或HANDLE。这些混淆了实际的数据类型,并且在那里使用匈牙利表示法可能会有好处。但是,如果可以在构建时知道数据的类型,为什么不使用适当的数据类型。

通常,没有硬性理由不使用匈牙利表示法。这取决于喜欢,政策和编码风格。


6

作为Python程序员,匈牙利符号法很快就瓦解了。在Python中,我不在乎某个东西是否是字符串-我在乎它是否可以字符串一样工作(即,如果它具有___str___()返回字符串的方法)。

例如,假设我们将foo作为一个整数,即12

foo = 12

匈牙利表示法告诉我们应该将其称为iFoo或类似的东西,以表示它是整数,以便以后我们知道它是什么。除了在Python中,这是行不通的,或者说,这没有任何意义。在Python中,我可以决定使用哪种类型。我想要一个字符串吗?好吧,如果我做这样的事情:

print "The current value of foo is %s" % foo

注意%s-字符串。Foo不是字符串,但是%运算符将调用foo.___str___()并使用结果(假设它存在)。foo仍然是整数,但是如果需要字符串,我们将其视为字符串。如果我们想要浮点数,则将其视为浮点数。在动态类型化的语言(如Python)中,匈牙利表示法是没有意义的,因为在使用某种类型之前,它与什么类型无关紧要;如果需要特定类型,则只需确保将其转换为该类型即可(例如float(foo))用它。

请注意,动态语言(如PHP)没有此好处-PHP会根据一套几乎没人记住的晦涩规则来尝试在后台执行“正确的事情”,这通常会导致灾难性的混乱。在这种情况下,诸如$files_count或的某种命名机制$file_name可能会派上用场。

在我看来,匈牙利表示法就像水ches。也许在过去它们是有用的,或者至少它们似乎有用,但是如今,它只是带来了很多额外的好处而已。


有趣的是,您在Python中使用.str()的示例并不是由于语言是动态的。Java,绝对不是一种动态语言,会做同样的事情。
垃圾工

C#也做同样的事情,该语言中的每个类都实现了.ToString()以便可以全部打印出来
Electric Coffee

5

IDE应该提供有用的信息。当IDE不够先进时,匈牙利人可能会产生某种意义(不是很多,而是某种意义)。


4
再说一次,您不应该依赖IDE告诉您更多信息。毕竟,可以在IDE外部查看代码...
TraumaPony

5

Apps Hungarian在我看来是希腊文-很好

作为工程师而不是程序员,我立即阅读了Joel撰写的有关Apps Hungarian优点的文章:“使代码看起来不正确”。我喜欢Apps Hungarian,因为它模仿工程,科学和数学如何使用子脚本和上标符号(例如希腊字母,数学运算符等)表示方程式和公式。以牛顿万有引力定律的特定示例为例:首先是标准数学符号,然后是Apps Hungarian伪代码:

牛顿关于地球和火星的万有引力定律

frcGravityEarthMars = G * massEarth * massMars / norm(posEarth - posMars)

在数学符号中,最突出的符号是表示 变量中存储的信息种类的:力,质量,位置矢量等。下标起到第二个作用,以澄清:位置是什么?这正是Apps Hungarian所做的;它先告诉您存储在变量中的东西的种类,然后再告诉细节-关于最接近的代码可以用数学符号表示。

显然,强类型输入可以解决Joel文章中的安全字符串与不安全字符串的示例,但是您不会为位置和速度矢量定义单独的类型。两者都是大小为3的双数组,您可能对其中一个所做的任何操作都可能适用于另一个。此外,连接位置和速度(以生成状态向量)或获取其点积,但可能不添加它们,是非常有意义的。键入将如何允许前两个而禁止第二个,这样的系统将如何扩展到您可能想要保护的所有可能的操作?除非您愿意在打字系统中对所有数学和物理学进行编码。

最重要的是,许多工程都是使用弱类型的高级语言(如Matlab)或旧语言(如Fortran 77或Ada)完成的。

因此,如果您有精通的语言,并且IDE和Apps Hungarian不能帮您,那么请忘记它-显然很多人都有。但是对我来说,这比使用弱语言或动态类型语言的新手程序员更糟糕,我可以使用Apps Hungarian更快地编写更好的代码。


4

对于大多数现代IDE来说,它具有令人难以置信的冗余性和无用性,它们在使类型明显化方面做得很好。

另外-对我来说-看到intI,strUserName等很烦人:)


3
正如TraumaPony告诉Paul Batum所说,并不是每个人都能在IDE中看到代码。
克里斯·查拉巴鲁克

4

如果我觉得正在传递有用的信息,为什么不把它放在可用的地方呢?

那么谁在乎别人的想法呢?如果您觉得有用,请使用符号。


“因为只有我一个人,还有不计其数的其他人以后可能会维护我的代码。由于所有这些人都在团队中(但他们还不知道),所以我想知道他们是否胜过我。
垃圾工

4

根据我的经验,这很糟糕,因为:

1-然后,如果需要更改变量的类型(即,需要将32位整数扩展为64位整数),则破坏所有代码。

2-这是无用的信息,因为类型已经在声明中,或者您使用动态语言,而实际的类型一开始就不那么重要。

此外,对于接受通用编程的语言(即,在编写函数时不确定某些变量类型的函数)或动态类型系统(即,在编译时甚至无法确定类型的语言),您将如何命名?变量?而且大多数现代语言都支持一种或另一种语言,即使是受限制的形式也是如此。


4

Joel Spolsky的“使代码看起来错误”中,他解释说每个人都认为匈牙利符号(他称为“系统匈牙利语”)并不是它的真正意图(他称其为Apps Hungarian)。向下滚动到“ 我是匈牙利”标题以查看此讨论。

基本上,系统匈牙利人一文不值。它只是告诉您编译器和/或IDE会告诉您的相同内容。

Apps Hungarian会告诉您该变量的含义,并且实际上可能有用。


4

我一直认为在正确的位置添加一个或两个前缀不会有任何问题。我认为,如果我可以传递一些有用的信息,例如“嘿,这是一个接口,不要指望特定的行为”,就像在IEnumerable中一样,我应该这样做。注释不仅会使一两个字符符号变得混乱,还会使事情变得混乱。


1
我从没说过。如果它是-able,则无论如何都意味着接口。(至少在Java中是这样)
tunaranch

4

如果控件列表显示在IDE中的字母下拉列表中,则这对于在表单(btnOK,txtLastName等)上命名控件很有用。


4

我倾向于仅将匈牙利表示法与ASP.NET服务器控件一起使用,否则我很难确定表单上的控件是什么。

请看以下代码片段:

<asp:Label ID="lblFirstName" runat="server" Text="First Name" />
<asp:TextBox ID="txtFirstName" runat="server" />
<asp:RequiredFieldValidator ID="rfvFirstName" runat="server" ... />

如果有人可以显示一种更好的方式来获得一组没有匈牙利语的控件名称,那么我很想转向它。


4

Joel的文章很棒,但似乎忽略了一个要点:

匈牙利语使特定的“想法”(种类+标识符名称)在整个代码库中甚至是非常大的代码库中都是唯一的或接近唯一的。

对于代码维护而言,这是巨大的。这意味着您可以使用出色的ol'单行文本搜索(grep,findstr,“在所有文件中查找”)来查找每个提及该“想法”的地方。

当我们拥有知道如何读取代码的IDE时,为什么这么重要?因为他们还不是很擅长。在一个小的代码库中很难看到这一点,但是在一个很大的代码库中却很明显-当在注释,XML文件,Perl脚本以及源代码控制之外的地方(文档,Wiki,Bug数据库)中可能提到“想法”时。

即使在这里,您也必须格外小心-例如,C / C ++宏中的令牌粘贴可能会隐藏标识符的提及。可以使用编码约定来处理这种情况,无论如何,它们往往只影响代码库中的少数标识符。

PS关于使用类型系统与匈牙利语的观点-最好同时使用两者。如果编译器无法为您找到所需的代码,则只需要使用错误的代码来查找错误。在很多情况下,使编译器无法捕获它是不可行的。但是在可行的地方-是的,请改为这样做!

但是,在考虑可行性时,请务必考虑拆分类型的负面影响。例如,在C#中,用非内置类型包装“ int”会产生巨大的后果。因此,在某些情况下(但并非在所有情况下)都有意义。


4

揭穿匈牙利符号的好处

  • 它提供了一种区分变量的方法。

如果类型是将一个值与另一个值区分开的全部,那么它只能用于将一种类型转换为另一种类型。如果您具有在类型之间转换的相同值,那么您应该在专用于转换的函数中执行此操作。(我看到匈牙利VB6剩菜在它们的所有方法参数上使用字符串,这仅仅是因为它们无法弄清楚如何反序列化JSON对象,或者无法正确理解如何声明或使用可为空的类型。)如果您有两个变量,它们仅以匈牙利前缀,并且它们不是从一个到另一个的转换,因此您需要详细说明使用它们的意图。

  • 它使代码更具可读性。

我发现匈牙利符号使人们对变量名感到懒惰。他们有一些可以区分的地方,他们认为不需要详细说明它的目的。这通常是在匈牙利标记的代码现代代码中找到的:sSQL相对于groupSelectSql(或者通常根本不使用sSQL,因为它们应该使用早期开发人员提供的ORM。),sValue与formCollectionValue(或通常没有sValue,因为它们恰好在MVC中,应该使用其模型绑定功能),sType与publishSource等。

它不是可读性。我从任何给定的匈牙利VB6剩余物中看到的sTemp1,sTemp2 ... sTempN比其他所有人的总和还多。

  • 它可以防止错误。

这将借助于数字2,这是错误的。


3

用大师的话说:

http://www.joelonsoftware.com/articles/Wrong.html

像往常一样有趣的阅读。

提取物:

“有人在某处阅读了Simonyi的论文,在其中他使用了“类型”一词,并认为他的意思是像类一样的类型,就像在类型系统中一样,就像编译器所做的类型检查一样。他没有。他非常仔细地解释。确切地说,他是“类型”一词的意思,但没有帮助。损坏已经造成。”

“但是,Apps Hungarian仍然具有巨大的价值,因为它增加了代码的并置,这使得代码更易于阅读,编写,调试和维护,并且最重要的是,它使错误的代码看起来不正确。”

在阅读Joel On Software之前,请确保您有一些时间。:)


现在没有时间我有了Stackoverflow。我认为Spolsky仅仅与该项目有关就必须这样做。:)
垃圾工

3

几个原因:

  • 任何现代的IDE都可以通过将鼠标悬停在变量上来为您提供变量类型。
  • 大多数类型名称都很长(请考虑HttpClientRequestProvider),可以合理地用作前缀。
  • 类型信息没有正确的信息,只是对变量声明进行了解释,而不是概述变量的用途(请考虑myIntegerpageSize)。

2

我不认为每个人都对此表示疯狂。在没有静态类型的语言中,它非常有用。当用于提供类型中尚未提供的信息时,我绝对喜欢它。像在C中一样,char * szName表示该变量将引用以null结尾的字符串-在char *中不是隐式的-当然,typedef也将有所帮助。

Joel撰写了一篇很棒的文章,介绍了如何使用匈牙利语来判断变量是否经过HTML编码:

http://www.joelonsoftware.com/articles/Wrong.html

无论如何,当匈牙利人用来传递我已经知道的信息时,我倾向于不喜欢它。


我认为第一句话可能就是本页上的答案。
垃圾工

@Dustman好了,你不知道C字符串是空终止?我确实看到了当字符串可能不是,但是很少见时,它将如何有用,所以我认为约定的使用应仅限于这些情况。
Plumenator 2012年

并非每个char *都是以null结尾的c字符串。匈牙利语的要点是将其用于每个变量,即使是常见的变量也是如此。最后,我觉得你这样做-因此我不C.使用它
娄佛朗哥


2

大约在发明匈牙利符号时,我就开始编写代码,而我第一次被迫在讨厌它的项目中使用它。

过了一会儿,我意识到正确地完成它确实可以帮上忙,这些天我很喜欢它。

但是,就像所有事物一样,必须学习和理解它,并且正确地进行操作需要时间。


1

匈牙利表示法被滥用,特别是被Microsoft滥用,导致前缀长于变量名,并且显示出它相当僵化的情况,尤其是当您更改类型时(臭名昭著的lparam / wparam,在Win16中具有不同的类型/大小,在Win32中相同) )。

因此,由于这种滥用及其被M $使用,都被认为是无用的。

在我的工作中,我们使用Java编写代码,但是创始人来自MFC世界,因此请使用类似的代码样式(大括号,我喜欢!),大写的是方法名,我习惯了,在类成员(字段,例如m_)前加前缀),s_到静态成员等)。

他们说所有变量都应该有一个前缀来显示其类型(例如,一个BufferedReader名为brData)。这是一个坏主意,因为类型可以更改,但名称不能跟随,或者编码器在使用这些前缀时不一致(我什至看到aBuffer,theProxy等!)。

就我个人而言,我选择了一些我认为有用的前缀,其中最重要的是b作为布尔变量的前缀,因为它们是我唯一允许使用语法if (bVar)(不使用将某些值自动转换为true或false)的变量。当我用C语言编写代码时,我为malloc分配的变量使用了前缀,以提醒您以后应释放它。等等。

因此,基本上,我总体上不拒绝这种说法,而是选择了适合我需要的内容。
当然,当为某个项目(工作,开源)做出贡献时,我只是使用了约定!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.