我在用Java编程时发生了什么:
String str
// want to call something(), but signature does not match
something(Foo foo)
// but I have this conversion function
Foo fooFrom(String)
// Obviously I am about to create another method overload.. sigh
something(String s) {
something(fooFrom(s));
}
但后来我想到了"自动类型转换"的可能性,它只使用我定义的转换函数fooFrom
每次传递字符串时,Foo对象除外。
我的搜索将我带到了维基百科页面,其中包含以下埃菲尔铁塔示例的类型转换:
class STRING_8
…
create
make_from_cil
…
convert
make_from_cil ({SYSTEM_STRING})
to_cil: {SYSTEM_STRING}
…
如果将STRING_8用作SYSTEM_STRING,则会自动调用convert
后的方法,反之亦然。 令我惊讶的是,我找不到任何其他语言支持这一点。
所以我的问题:还有其他语言支持此功能吗? 如果没有,有什么原因吗,因为它对我来说似乎很有用? 此外,我认为将其作为语言附加组件实现并不困难。
有一个小问题可能会使事情变得更加复杂。目前,Eiffel 有一个规则,即只有当重新附着的源附加到对象时,才能应用转换,即不是Void(在 Java/C# 中不是空)。
让我们看一下原始示例:
something (str);
假设str为空。我们是否得到一个 NullPointerException/InvalidArgumentException,因为代码被转换为
something (fooFrom (str));
和fooFrom不期望为空?或者编译器是否足够聪明,可以将其转换为
if (str == null)
something (null);
else
something (fooFrom (str));
?
当前的埃菲尔标准确保此类问题根本不会发生,如果涉及转换,str不为空。然而,许多其他语言(如Java或C#)并不能保证这一点,额外的复杂性可能不值得为它们付出努力。
我相信 Eiffel 不是唯一支持转换例程的语言,但我想说它可能是极少数将其与语言定义其余部分很好地集成的语言之一。
例如,在 .NET 中,你同时具有可用于转换支持它们的语言的op_Explicit例程和op_Implicit例程。我相信 C# 确实如此。
马努
类型强制(隐式转换)是一种诅咒和祝福——在某些情况下很方便,但它也可能适得其反。
例如,Javascript有许多奇怪的强制规则,当强制字符串到数字等时,这可能会导致错误。
Scala有一种叫做"隐式"的东西,它实现了类似于你在埃菲尔铁塔中描述的东西(至少对我来说)。毫不奇怪,它们可能会导致某些陷阱。但它们也可以非常方便,例如参见文章皮条客我的图书馆。
C++具有复制构造函数和赋值运算符。