为什么擦除会使函数类型的实现变得复杂?
我从对 Neal Gafter 的采访中读到:
“例如,使用 Erasure 作为泛型的一部分,向编程语言添加函数类型要困难得多。”
编辑: 我遇到类似声明的另一个地方是 Brian Goetz 的 Lambda Dev 邮件列表中的消息,他说当 lambda 只是带有语法糖的匿名类时,它们更容易处理:
但我对函数类型的反对并不是因为我不喜欢函数类型——我喜欢函数类型——而是函数类型与 Java 类型系统的现有方面(擦除)发生了激烈的冲突。擦除的函数类型是两全其美的。所以我们从设计中删除了它。
谁能解释这些说法?为什么我需要 lambda 的运行时类型信息?
I read from an interview with Neal Gafter:
"For example, adding function types to the programming language is much more difficult with Erasure as part of Generics."
EDIT:
Another place where I've met similar statement was in Brian Goetz's message in Lambda Dev mailing list, where he says that lambdas are easier to handle when they are just anonymous classes with syntactic sugar:
But my objection to function types was not that I don't like function types -- I love function types -- but that function types fought badly with an existing aspect of the Java type system, erasure. Erased function types are the worst of both worlds. So we removed this from the design.
Can anyone explain these statements? Why would I need runtime type information with lambdas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我的理解是,他们认为,由于擦除,走“函数类型”的路会很混乱,例如 C# 中的委托,他们只能使用lambda 表达式,这只是单一抽象方法类语法的简化。
C# 中的委托:(
这里是另一个示例
http://geekswithblogs.net/joycsharp/archive /2008/02/15/simple-c-delegate-sample.aspx)
他们在 Lambda 项目文档中提出的一个论点:
第 2 节:
http://cr.openjdk.java.net/~briangoetz /lambda/lambda-state-3.html
(最终的 lambda 表达式语法与上述文档略有不同:
http://mail.openjdk.java.net/pipermail /lambda-dev/2011-September/003936.html)
总而言之,我最好的理解是,只有一部分语法内容实际上可以是 用过的。
Neal Gafter 最有可能的意思是,无法使用委托将使标准 API 更难以适应函数式风格,而不是 javac/JVM 更新将更难完成。
如果有人比我更理解这一点,我会很乐意阅读他的帐户。
The way I understand it, is that they decided that thanks to erasure it would be messy to go the way of 'function types', e.g. delegates in C# and they only could use lambda expressions, which is just a simplification of single abstract method class syntax.
Delegates in C#:
(another sample here
http://geekswithblogs.net/joycsharp/archive/2008/02/15/simple-c-delegate-sample.aspx)
One argument they put forward in Project Lambda docs:
section 2 in:
http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3.html
(The final lambda expressions syntax will be a bit different from the above document:
http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html)
All in all, my best understanding is that only a part of syntax stuff that could, actually will be used.
What Neal Gafter most likely meant was that not being able to use delegates will make standard APIs more difficult to adjust to functional style, rather than that javac/JVM update would be more difficult to be done.
If someone understands this better than me, I will be happy to read his account.
Goetz 在 State of the Lambda 第四版中扩展了推理。< /a>:
请注意,擦除只是考虑因素之一。一般来说,Java lambda 方法与 Scala 的方向不同,而不仅仅是在类型问题上。它非常以 Java 为中心。
Goetz expands on the reasoning in State of the Lambda 4th ed.:
Note that erasure is just one of the considerations. In general, the Java lambda approach goes in a different direction from Scala, not just on the typed question. It's very Java-centric.
也许是因为您真正想要的是类型
Function
,它使用返回类型和一些参数类型序列进行参数化。但由于擦除,你不能有像P...
这样的构造,因为它只能变成Object[]
,它太松散而没有多大用处在运行时。这纯粹是猜测。我不是一个类型理论家;我是一个类型理论家。我什至都没在电视上玩过。
Maybe because what you'd really want would be a type
Function<R, P...>
, which is parameterised with a return type and some sequence of parameter types. But because of erasure, you can't have a construct likeP...
, because it could only turn intoObject[]
, which is too loose to be much use at runtime.This is pure speculation. I am not a type theorist; i haven't even played one on TV.
我认为他在那句话中的意思是,在运行时Java无法区分这两个函数定义之间的区别:
因为在编译时,有关List包含的数据类型的信息被删除,因此运行时环境将无法区分以确定您要调用哪个函数。
尝试在同一个类中编译这两个方法将引发以下异常:
I think what he means in that statement is that at runtime Java cannot tell the difference between these two function definitions:
Because at compile time, the information about what type of data the List contains is erased, so the runtime environment wouldn't be able to determine which function you wanted to call.
Trying to compile both of these methods in the same class will throw the following exception: