是什么使斯卡拉的运算符重载“良好”,但C ++的‘坏’?(What makes Scala'

2019-06-25 10:28发布

C ++操作符重载被许多人认为是一件坏事(TM),而不是一个错误,在新的语言重复。 当然,这是一个特点设计的Java的时候,特意删除。

现在,我已经开始对斯卡拉读,我觉得它有什么看起来非常像运算符重载(虽然技术上它不具有运算符重载,因为它没有运营商中,只有函数)。 然而,这似乎不会成为对运营商在C ++中,在那里我记得运营商被定义为特殊功能超载质的不同。

所以我的问题是什么使Scala中定义“+”一个更好的主意比在C ++的想法?

Answer 1:

C ++继承了真正的蓝运营商从C,我的意思是,“+” 6 + 4是非常特殊的。 你不能,例如,获得一个指向+功能。

斯卡拉,另一方面没有以这种方式运营。 它只是在定义方法的名字很大的灵活性,再加上一点点建在优先为无字符号。 因此从技术上讲Scala没有操作符重载。

无论你怎么称呼它,运算符重载本身不是坏的,即使是在C ++。 问题是当不好的程序员滥用它。 但坦率地说,我认为,带走程序员滥用运算符重载不放在固定所有的程序员可以滥用的东西杯水车薪能力。 真正的答案是师徒。 http://james-iry.blogspot.com/2009/03/operator-overloading-ad-absurdum.html

无最少,有C ++的操作符重载和Scala的灵活方法命名其中,IMHO,使Scala中均不可滥用和多种可滥用之间的差异。

在C ++中得到修复符号是使用运营商的唯一途径。 否则,您必须使用object.message(参数)或指针 - >讯息话题(参数)或函数(参数1,参数2)。 所以,如果你想一定DSLish风格,你的代码有压力使用运营商。

在Scala中,你可以得到任何消息发送缀表示法。 “对象的消息的说法”是完全正常的,这意味着你不需要使用无字符号只是为了让缀表示法。

C ++操作符重载被限制为基本上C运算符。 与运营商只可以使用中缀是把压人尝试各种不相关的概念映射到像“+”和相对较少的符号的限制相结合“>>”

斯卡拉允许一个巨大的有效的非字符号的方法名范围。 举例来说,我有一个嵌入式的Prolog十岁上下的DSL,你可以写

female('jane)!         // jane is female
parent('jane,'john)!   // jane is john's parent
parent('jane, 'wendy)! // jane is wendy's parent

mother('Mother, 'Child) :- parent('Mother, 'Child) & female('Mother) //'// a mother of a child is the child's parent and is female

mother('X, 'john)?  // find john's mother
mother('jane, 'X)?  // find's all of jane's children

本: - , - ,和&符号被定义为普通的方法!?。 在C ++只&将是有效的,从而试图将该DSL映射到C ++将要求已经引起非常不同的概念一些符号。

当然,这也打开了斯卡拉另一种虐待。 在Scala中您可以命名一个方法$!^&%,如果你想。

对于其他语言,像斯卡拉,都在使用非词功能和方法的名称灵活看到Smalltalk的地方,比如Scala,每一个“经营者”仅仅是另一种方法和Haskell允许程序员定义优先级和固定性的灵活命名功能。



Answer 2:

操作者在C ++超载被许多人认为是坏事(TM)

只有无知。 这是绝对必要的,如C ++语言,并且值得注意的是,该开始时采取“纯粹”的看法等语言,增加了一次他们的设计师发现它是多么必要。



Answer 3:

运算符重载从未被普遍认为是C ++是一个坏主意 - 运算符重载的只是滥用被认为是一个坏主意。 一个并不真正需要的运算符重载的语言,因为他们可以用更详细的功能调用反正来模拟。 避免操作者在Java中重载由Java的简单一点的实现和规范,并迫使程序员不能滥用运营商。 目前已经在Java社区中关于引入运算符重载一些争论。

优点和斯卡拉超载运营的缺点是一样的C ++ - 更隐蔽,模糊的代码,如果你不这样做 - 如果你使用操作符重载适当的,你可以写出更自然的代码。

FYI:运营商不是在C ++定义为特殊功能,它们的行为就像任何其他的功能 - 虽然在名称查找一些差异,是否他们需要的是成员函数,而事实上,他们可以通过两种方式调用:1 )运算符的语法,和2)操作员功能-ID的语法。



Answer 4:

这篇文章- “ C的正面遗产++和Java ” -直接回答你的问题。

“C ++既有堆栈分配和堆分配,你必须重载你的运营商来处理所有的情况,不会造成内存泄漏。难矣。Java的,但是,有一个单一的存储分配机制和垃圾收集器,这使得运算符重载微不足道”。 ..

Java的错误(据笔者)省略操作符重载,因为它是在C ++复杂,却忘了为什么(或没有意识到它并不适用于Java的)。

值得庆幸的是,更高层次的语言,像斯卡拉给开发者的选择,同时仍然在同一个JVM上运行。



Answer 5:

没有什么错运算符重载。 事实上,有一些错误与具有运算符重载数字类型。 (看看使用BigInteger和BigDecimal的一些Java代码。)

C ++有滥用特征的传统,虽然。 一个经常引用的例子是位移操作符提升重载做I / O。



Answer 6:

总的来说这是不是一件坏事。
新的语言,如C#也有运算符重载。

这是操作符重载滥用是一件坏事。

但也有在C ++中定义运算符重载问题。 由于重载运算符都只是方法调用的语法糖,他们的表现就像方法。 在另一方面正常内置运营商不表现得像方法。 这些矛盾可能是导致问题。

把我的头运营商的顶||&&
内置的这些版本是短切运营商。 这不是重载版本真实,已经引起了一些问题。

事实上,+ - * /全部返还相同种类,它们在操作(操作后晋升)
该重载版本可以返回任何东西(这是滥用集,如果你的运营商开始返回一些仲裁类型的用户没想到的事情走下坡路)。



Answer 7:

运算符重载是不是你真正的“需要”非常频繁,但使用Java的时候,如果你打一个地步,你真正需要它,它会让你想要撕裂你的指甲出来只是让你有借口停止打字。

您刚才发现溢出代码长时间? 是啊,你将不得不重新输入一大堆,使其与BigInteger的工作。 没有什么更令人沮丧的是不必推倒重来只是改变一个变量的类型。



Answer 8:

盖伊·斯蒂尔认为,操作符重载应在Java中,以及在他的主题演讲“成长的语言” - 有一个视频,它的转录,这真是一个惊人的言论。 你会不知道他在谈论的前几页,但如果你继续阅读,你会看到这一点,并得到启迪。 和张女士,他可以不惜一切做这样的演讲也是惊人的。

与此同时,这次谈话启发了很多基础研究,其中很可能包括斯卡拉 - 这是这些论文,每个人都应该阅读领域的工作之一。

回到点,他的例子大多是关于数字类(如BigInteger,它和一些怪异的东西),但是这不是必需的。

这是事实,但是,运算符重载的是滥用可导致可怕的后果,而且即使正确使用,可以使问题复杂化,如果你尝试不研究了一下它使用的库来读取代码。 但是,这是一个好主意? OTOH,不应该这样的库尝试包括为他们的运营商运营商小抄?



Answer 9:

我相信每一个答案,错过了这个。 在C ++中,你可以重载运营商所有你想要的,但你不能影响与他们评估的优先级。 Scala没有这个问题,IIRC。

至于它是一个坏主意,除了优先级的问题,人们想出了为运营商真正愚蠢的含义,它很少帮助可读性。 斯卡拉库这一点,你必须每次都记住,随着库的维护者坚持自己把头埋在沙说法愚蠢的符号,特别是坏,“你只需要学习一次它”。 太好了,现在我需要学习一些“聪明”作者的神秘语法*我不在乎使用图书馆的数量。 它不会如此糟糕,如果存在着总是供应商的识字版本的约定。



Answer 10:

运算符重载不是C ++的发明 - 它来自陵IIRC甚至戈斯林不主张这是一般一个坏主意。



Answer 11:

在C ++中已知错误的唯一事情是缺乏的重载[] =作为单独的操作者的能力。 这可能是很难在C ++编译器来实现,什么是可能不是一个明显的原因,但很多值得。



Answer 12:

至于其他的答案人士指出, 运算符重载本身不一定是坏事。 当它的方式,使产生的代码未明显使用什么是坏它。 一般在使用它们时,你需要让他们做的至少令人吃惊的事情(有运营商+做到分工将导致一个合理的类的使用麻烦),或作为斯科特迈尔斯说:

客户已经知道如何类型如int的行为,所以你应该努力让你的类型以同样的方式,只要合理的行为...... 如果有疑问,请为整数做 。 (从有效C ++第三版项目18)

现在有些人已经采取运算符重载的东西,如极端的boost ::精神 。 在这个层面上,你不知道它是如何实现的,但它使一个有趣的语法来得到你想要做的事情。 我不知道这是好还是坏。 这似乎不错,但我没有用它。



Answer 13:

我从来没有见过的一篇文章声称,C ++的操作符重载是坏的。

用户可定义的经营许可证表达性和可用性,为语言的用户更容易的更高的水平。



Answer 14:

然而,这似乎不会成为对运营商在C ++中,在那里我记得运营商被定义为特殊功能超载质的不同。

据我所知,没有什么特别的操作功能相比,“正常”的成员函数。 当然,你只需要一组特定的,你可以重载运营商,但是这并不能让他们很特别。



文章来源: What makes Scala's operator overloading “good”, but C++'s “bad”?