虽然,这与我读过的第二篇论文“可插拔型系统”(PDF)有关。看来,Gilad Bracha认为推理部分不应该是编译器的一部分,而是IDE 特征 </跨度> 或……类似(上述文件第4节第6段):
一个更好的 工程 </跨度> 方法是 将类型推断实现为单独的 工具,可在IDE中使用。 找到输入类型的程序员 注释很烦人可以调用 按需推断。
你怎么看? …
这是一个有趣的,非常有趣的话题,与研究相关,而不是与实际(即当前)编程相关。
首先要做的事情。关于Java中的var,实际上没有理由实现它,它们已经拥有了“技术”。但是,泛型仅在系统的编译器端,这意味着在其运行时,VM只是使用对Object的引用,并且由于编译器注入的代码(再次在编译时),它们被适当地转换。但是,在C#中,泛型在编译之后会存在。
其次,关于Bracha的那篇(非常有趣的)论文,你应该看看我们的StaDyn项目,一种类似C#的编程语言。类型系统实际上是可插入的,即您可以像普通C#一样使用它,或者根本不使用它,并体验完全动态的语言。
http://www.reflection.uniovi.es/stadyn/
好吧,我认为类型推断 是 在Java中 历史的 主要原因是:为了适应具有强大遗留约束的语言,Java的改进是谨慎的。逐渐地(作为 JCP 显示,即使有些 改进 类型推断管理 经过 )。随着仿制药,长期存在 GJ 在包含在Java 5之前,对实现进行了全面评估。
在Java 5发布之前,Java中没有类型推断。 (...)当在Java 5中引入泛型(...)时,该语言保留了对变量,方法和分配的这一要求。但是多态方法的引入(按类型参数化)决定了(i)程序员在每个多态方法调用站点提供方法类型参数或(ii)语言支持方法类型参数的推断。为避免给程序员带来额外的文书负担,Java 5的设计者选择执行类型推断来确定多态方法调用的类型参数。 ( 资源 )
但这并不意味着Java中存在普遍类型推理的强大文化。按照 规范 :
另请注意,类型推断不会以任何方式影响健全性。如果推断的类型是无意义的,则调用将产生类型错误。类型推断算法应被视为启发式算法,旨在在实践中表现良好。如果它无法推断出期望的结果,则可以使用显式类型参数。
的 我认为Java的更多类型推断将是一个福音 强> (斯卡拉已经是一个 非常有趣的改进 在那个方向)。恕我直言, 类型推断使得类型检查器的反馈循环不那么机械,同时就像声音一样 ,让你写更少的类型,但让你进行类型检查同样多。由于类型的主要好处是 的 指导程序搜索的心理过程 强> (” 让你在良好类型的节目空间内写作,而不是在ascii turds空间 “),与类型检查器交互的这种舒适感似乎非常宝贵:你可以使用类型检查器来验证你是否用良好的术语进行思考 并训练你这样做 而不是让你在每一行都考虑到它。
现在 阶段 哪种类型推断应该发生是另一个问题。我认为希望将“推理器”与运行时区分开来解决传统问题:它避免要求您使用始终向后兼容的类型推断算法。但关键是你的标准/主要库看起来像:你发布的源和&amp;是否与其他人交换注释?
虽然无论你的推理引擎的强度如何都可以有价值地对带注释的源进行类型检查,但我仍然需要在编译器中使用类型推理器,因为它不仅仅是我不想要的 写 List<CacheDecoratorFactory> cacheDecoratorFactories = new ArrayList<CacheDecoratorFactory>(); ,这是我不想要的事情 读 它。在重构预先存在的源时,我也不想处理它。在与源交互之前,我需要一个类型“hider”擦除注释,但是如果类型推理引擎是 不 完成,问题 哪一个 要删除的注释,并确保类型重建后的擦除是 双射 变得棘手(特别是如果你的推理引擎没有返回 主要类型 )...如果我们必须解决一个棘手的问题 无论如何 ,为什么不把它作为一个好的,尽可能完整的类型推理算法?我的预感是,经过一定程度的质量(特别是返回类型的一般性),遗留问题将开始消退。
List<CacheDecoratorFactory> cacheDecoratorFactories = new ArrayList<CacheDecoratorFactory>();
这不是一个真正的答案,但从侧面说明,你可能想要研究D语言。它允许您编写如下代码:
int*[6]*[wstring][]*[string]*[] myVar; auto myVar2 = new typeof(myVar[0])[100]; // equivalent to: new int*[6]*[wstring][]*[string]*[]*[string]*[100]
基本上,它是手动推理+自动推理,它可以让你编写非常通用的代码,用其他语言编写起来比较困难。 (这里的例子不太现实,但它说明了这一点。)
类型推断在IntelliJ中可用,也可能在其他IDE中可用。您可以编写表达式(或使用现有表达式)并选择“引入字段/局部变量/常量”等,它将为您提供一些推断的类型选项和一些建议的名称。如果表达式出现多次,则可以选择替换所有出现的内容。例如说我有一个字符串我想变成一个参数
myMethod(); public void myMethod() { "/tmp/20101112/data.file" }
我选择了日期部分和&lt; ctrl&gt; +&lt; alt&gt; + P,它建议添加一个int类型作为参数。它会将此日期内联到所有呼叫者。
myMethod(20101112); public void myMethod(int date) { "/tmp/"+date+"/data.file" }
我在开始时放置“new FileInputStream(”并引入局部变量。&lt; ctrl&gt; +&lt; alt&gt; + V
FileInputStream fileInputStream = new FileInputStream("/tmp/"+date+"/data.file");
它强调这可以抛出异常,我可以自动修复多种方式。我选择&lt; alt&gt; +&lt; enter&gt;并将该异常添加到方法的throws子句中。
myMethod(20101112); public void myMethod(int date) throws FileNotFoundException { FileInputStream fileInputStream = new FileInputStream("/tmp/"+date+"/data.file");
恕我直言,让IDE完成工作更有意义,因为它可以比编译器更加交互,并且您可以明确地看到您的类型变成了什么。