我知道这已经讨论了很多次,但我不确定我是否真的理解为什么 Java和C#设计者选择从这些语言中省略这个功能。我对如何制定变通方法(使用接口,克隆或任何其他替代方法)不感兴趣,而是对决策背后的基本原理感兴趣。
从语言设计的角度来看,为什么这个功能被拒绝了?
P.S:我正在使用诸如“省略”之类的词语,有些人可能觉得这些词语不合适,因为C#是用加法(而不是减法)方法设计的。但是,我使用这样的词是因为在设计这些语言之前,C ++中存在这个特性,所以从程序员的工具箱中删除它就省略了。答案 0 :(得分:15)
在this采访中,安德斯说:
Anders Hejlsberg:是的。关于 const,这很有意思,因为我们 也一直听到这个抱怨: “为什么你没有const?”含蓄 在问题是,“你为什么不 有const由强制执行 运行时?“那真是人 正在问,虽然他们不来 出去说那样。
const在C ++中工作的原因是 因为你可以扔掉它如果你 无法抛弃它,然后是你的世界 会很糟糕如果您声明一个方法 需要一个const Bla,你可以通过 它是一个非常规的Bla。但如果是的话 你的其他方式不能。如果你 声明一个采用a的方法 非const Bla,你不能传递它 const Bla。所以现在你被卡住了。那么你 逐渐需要一个const版本 一切都不是常数,而你 结束了阴影世界。在C ++中你 侥幸逃脱,因为和 C ++中的任何东西都是纯粹可选的 你是否想要这个检查。 你可以打破常量 如果你不喜欢它。
答案 1 :(得分:7)
我猜主要是因为:
两者都有问题。但特别是第一个:如果不能保证,它有什么用?更好的选择可能是:
答案 2 :(得分:1)
至于他们为什么这样做,所涉及的人都这么说:
http://blogs.msdn.com/ericgu/archive/2004/04/22/118238.aspx http://blogs.msdn.com/slippman/archive/2004/01/22/61712.aspx Raymond Chen也提到过 http://blogs.msdn.com/oldnewthing/archive/2004/04/27/121049.aspx
在多语言系统中,这将非常复杂。
答案 3 :(得分:1)
对于Java,你会如何表现这样的属性?已经存在使对象不可变的技术,这可以说是通过额外的好处实现这一目标的更好方法。实际上,您可以通过声明仅实现不更改状态的方法的超类/超接口来模拟const行为,然后使用实现变异方法的子类/子接口。通过将可变类转发到没有写入方法的类实例,其他代码不能修改对象而不将其专门强制转换回可变版本(这相当于抛弃const
)。
即使你不希望对象是严格不可变的,如果你真的想要(我不推荐),你可以在它上面设置某种“锁定”模式,这样它只能在解锁时发生变异。将锁定/解锁方法设置为私有或适当保护,并在那里获得某种级别的访问控制。或者,如果您不打算将该方法作为参数进行修改,则传入该对象的副本,或者如果复制整个对象太重,那么其他一些轻量级数据对象只包含必要的信息。您甚至可以使用动态代理为对象创建代理,将任何对变异方法的调用转换为无操作。
基本上已经有很多方法可以防止类被突变,这可以让你选择一个最适合你情况的方法(提示:尽可能选择纯粹的不变性,因为它使对象简单地线程安全且更容易推理一般而言)。没有明显的语义可以实现const
如何对这些技术进行改进,这将是另一件事,要么学会缺乏灵活性,要么灵活到无用。
即使我错过了一些东西,这是完全可能的。 : - )
答案 4 :(得分:0)
Java有自己的const版本;最后。 Joshua Bloch在他的Effective Java中描述 如何有效地使用final关键字。 (顺便说一句,const是Java中的保留关键字,用于未来的差异)