【问题标题】:What is wrong with inferred type of template and implicit type conversion?推断的模板类型和隐式类型转换有什么问题?
【发布时间】:2015-03-21 08:20:32
【问题描述】:

我正在阅读 Andrei Alexandrescu 的“The D Programming Language”,其中一句话让我感到困惑。考虑这样的代码(p.138):

T[] find(T)(T[] haystack, T needle) {
   while (haystack.length > 0 && haystack[0] != needle) {
      haystack = haystack[1 .. $];
   }
   return haystack;
}

并调用 (p.140):

double[] a = [ 1.0, 2.5, 2.0, 3.4 ];
a = find(a, 2); // Error! ' find(double[], int)' undefined

解释(代码下方的段落):

如果我们足够用力地眯着眼睛,我们确实会看到在这种情况下调用者的意图是拥有T = double 并受益于从intdouble 的良好隐式转换。但是,在一般情况下,让语言同时尝试组合隐式转换和类型推导是一个冒险的命题,因此 D 不会尝试做所有这些。

我很困惑,因为像 C# 这样的语言试图推断类型——如果它不能做到这一点,用户就会得到错误,但如果它可以,那么它可以工作。 C# 与它一起生活了好几年,我没有听说过这个功能如何毁了某人的一天。

所以我的问题是——在上面的例子中推断类型有什么危险?

我只看到优点,泛型函数容易写,调用也容易。否则,您将不得不在泛型类/函数中引入更多参数,并编写特殊约束来表达允许的转换,只是为了推断类型。

【问题讨论】:

标签: c# templates generics d


【解决方案1】:

首先要注意的是,并不是说类型推导有问题,而是类型推导隐式转换同时有问题强>。

所以,如果你有:

a = find(a, 2.0);

那么很高兴推断double为类型。

如果显式键入 double,很高兴推断 2 应该隐式转换为 2.0

它不会同时做的。

现在,C# 确实做到了。而且我认为在很大程度上我同意你的看法,它通常很方便,而且效果很好。

同时它确实可能令人困惑,尤其是在它导致不止一个同样合理的过载的情况下。

Why type inference and implicit operator is not working in the following situations?Why does Assert.AreEqual on custom struct with implicit conversion operator fail? 都是关于为什么隐式转换和类型推断的特定组合不起作用的问题。

Unexpected effect of implicit cast on delegate type inference 有其他因素,但再次拒绝考虑可能匹配列表中的方法,因为参数类型不匹配意味着问题没有发生。

如果答案总是“因为您同时进行隐式转换和类型推断,并且不支持”,那么它们都会简单得多。这就是 D 的答案。

另一方面,虽然这样的问题并不经常出现,所以我仍然赞成 C# 设计决定允许两者,但存在一些问题意味着不允许它们仍然是一个合理的设计决定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 2013-12-27
    • 2016-01-23
    相关资源
    最近更新 更多