【发布时间】:2015-05-16 06:54:59
【问题描述】:
有时可能希望将x 声明为与y 相同的类型。使用vals 类型推断可以很好地处理这个问题,但这在其他一些领域不起作用,比如with function types。
对于具有一定 C++ 经验的程序员来说,一个显而易见的解决方案是decltype。当前的 Scala 中似乎没有这样的设施。
链接问题的答案表明:
因为类型不是一等公民
我不得不承认我不明白这一点。我不认为类型是 C++ 中的一等公民,但它仍然可以拥有decltype。对于泛型中的类型参数或类似的东西,我没有询问类似decltype 的任何东西(我知道泛型不是模板,类型在其中被删除)。尽管如此,我认为一个允许我在需要类型的地方使用表达式类型的运算符 - 当然编译器必须能够评估表达式类型,否则val定义的类型推断将是不可能的.
decltype 可以像下面这样使用 - 代码并没有尝试做任何有用的事情,只是为了说明语法和基本用法:
case class A(x:Int = 0)
val a = new A(10)
val b = new decltype(a)
def f(c:decltype(a)) : decltype(a.x+a.x)
decltype 的缺席是一个深思熟虑的决定,还是 Scala 不能拥有它的一些具体原因?是否有一些使用编译时反射的解决方案可以允许这样做?
【问题讨论】:
-
b如何在这里发挥作用? -
@m-z b 在这里只是作为一个例子。在这种特殊情况下,它与 val b = a 相同,但人们可以很容易地想象类似的情况,它不会相同。我会尝试更新问题。
-
我不明白这个问题。类型签名是编译时的,因此您必须能够静态指定类型。那
decltype的东西给了你什么?常规val b: A = a和def f(c: A): A的“缺点”是什么? -
@0__ 静态并不一定意味着程序员能够提供类型名称。
def(c: A): A不等价,返回类型其实是Int(a.x+a.x的类型),这种情况下可以用返回类型推断来克服,但也有不能用的情况,不能用这种方法如果您正在定义抽象方法或函数签名。一个突出的例子是另一个问题中写的函数类型。在 Scala 中已经有一个先例,编译器评估表达式的类型 - 单例类型。 -
@0__ 问题是你可能不知道A型;你可能有 val a = someFuncton(whatever) 返回一个你不应该知道的类型,你可能想使用那个类型;例如,作为 List 或 Future 等通用类的参数。在 C++ 中,decltype(x) 是表达式 x 的静态类型。
标签: scala type-inference decltype