【问题标题】:Why was constness removed from Java and C#?为什么从 Java 和 C# 中删除 constness?
【发布时间】:2010-10-03 17:37:58
【问题描述】:

我知道这已经讨论过很多次了,但我不确定我是否真的理解为什么Java 和 C# 设计者选择从这些语言中省略这个特性。我对如何制定变通办法(使用接口、克隆或任何其他替代方法)不感兴趣,而是对决定背后的基本原理感兴趣。

从语言设计的角度来看,为什么这个功能被拒绝了?

P.S:我使用了诸如“省略”之类的词,有些人可能会觉得这不够用,因为 C# 是采用加法(而不是减法)方法设计的。但是,我之所以使用这些词,是因为在设计这些语言之前,C++ 中就存在该功能,因此在从程序员的工具箱中删除的意义上省略了它。

【问题讨论】:

  • 我想知道为什么这个问题被否决了?!
  • 可能会引发主观/争论性讨论,尽管问题中的措辞确实问的是“为什么设计师选择这样做”而不是为什么这是一件好事/坏事。

标签: c# java c++ programming-languages language-features


【解决方案1】:

我猜主要是因为:

  • 即使在 C++ 中也无法正确执行(您可以强制转换)
  • 底部的单个 const 可以强制调用树中的整个 const 链

两者都可能有问题。但尤其是第一个:如果不能保证,那有什么用?更好的选择可能是:

  • 不可变类型(完全不可变或冰棒不可变)

【讨论】:

  • 如果在某个地方不能保证,那么应该封装那个地方。或者,如果文档承诺不调整任何输入并且确实没有,那么这是 const_cast 的有效用例,即与 const 不正确的代码互操作。与安全帽一样,它们提供限制和保护。
【解决方案2】:

this采访中,安德斯说:

安德斯·海尔斯伯格:是的。关于 const,这很有趣,因为我们 也一直听到这种抱怨: “你为什么没有 const?”隐式 问题是,“你为什么不 有 const 由 运行时?”这就是人们所说的 在问,虽然他们不来 出来这样说。

const 在 C++ 中起作用的原因是 因为你可以把它扔掉。如果你 不能把它扔掉,然后你的世界 会很烂。如果你声明一个方法 这需要一个 const Bla,你可以通过 它是一个非常量 Bla。但如果是 其他方式你不能。如果你 声明一个方法,该方法采用 非常量 Bla,你不能通过它 常量布拉。所以现在你被卡住了。那么你 逐渐需要一个 const 版本的 所有不是 const 的东西,而你 以阴影世界告终。在 C++ 中,你 摆脱它,因为与 C++ 中的任何内容都是可选的 不管你是否想要这个检查。 你可以把常事打掉 如果你不喜欢它。

【讨论】:

  • 这可能是一种逃避,因为他知道得更清楚。如果你正确地声明了一个 foo(Bla&),那是有原因的:它修改了 Bla。您不要添加 foo(Bla const&) 因为它无法工作。如果 foo 被意外声明 (Bla&) 但它没有修改 Bla,您可以安全地只添加 const。无需超载。
  • 缺少 const-ref 恕我直言,这是 .NET 中最大的设计缺陷之一。我同意 Hejlsberg 先生的观点,即为 const 正确性设计是困难的,但语义 const 正确性通常是程序正常工作所必需的,无论框架是否提供它,并且 const 正确性更容易实现,如果它是自下而上的设计,而不是以后不得不捏造它。
【解决方案3】:

至于他们为什么这样做,相关人士已经说了:

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

在多语言系统中,这将非常复杂。

【讨论】:

    【解决方案4】:

    对于Java,你会如何拥有这样的属性?已经有使对象不可变的技术,这可以说是实现这一目标的更好方法,并具有额外的好处。事实上,你可以通过声明一个只实现不改变状态的方法的超类/超接口,然后拥有一个实现变异方法的子类/子接口来模拟 const 行为。通过将可变类向上转换为没有写入方法的类实例,其他代码位无法修改对象,除非专门将其转换回可变版本(相当于丢弃const)。

    即使你不希望对象是严格不可变的,如果你真的想要(我不推荐)你也可以在它上面设置某种“锁定”模式,这样它只能在解锁时改变.让锁定/解锁方法是私有的,或者适当地受到保护,并且您可以在那里获得某种程度的访问控制。或者,如果您根本不打算将该方法作为参数来修改它,请传入该对象的副本,或者如果复制整个对象过于繁重,那么其他一些仅包含必要的轻量级数据对象信息。您甚至可以使用动态代理为您的对象创建一个代理,将任何对变异方法的调用变为无操作。

    基本上,已经有很多方法可以防止类发生变异,这让您可以选择最适合您的情况的方法(提示:尽可能选择纯不变性,因为它使对象变得简单线程安全并且更容易推理一般情况下)。对于如何实现 const 没有明显的语义,这将是对这些技术的改进,学习这将是另一回事,要么缺乏灵活性,要么灵活到无用。

    也就是说,除非我错过了什么,这是完全可能的。 :-)

    【讨论】:

    • 可以说“const”将可变对象变成不可变对象,无需额外代码。对于不可变类型,您通常会得到第二种“构建器”类型。 -- 一般来说,我喜欢“const”的声明性表达;虽然我同意这是一罐蠕虫。
    【解决方案5】:

    Java 有自己的 const 版本;最终的。 Joshua Bloch 在他的Effective Java 你如何有效地使用 final 关键字。 (顺便说一句,const 是 Java 中的保留关键字,以备将来出现差异)

    【讨论】:

    • final 与 const 有很大不同,它只是它的一个影子。 c# 中的 readonly 与 java 中的 final 等效,只是它不能应用于局部变量(IMO 很遗憾)。 const 也是 c# 中的保留字,出于同样的原因
    猜你喜欢
    • 2023-04-01
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多