什么时候Scala需要匿名和扩展函数的参数类型?
什么时候
Scala编译器真的需要匿名函数参数的类型信息?
例如,给定此功能: def callOn[T,R](target: T,f: (T => R)) = f(target) 然后我不能这样使用它: callOn(4,_.toString) => error: missing parameter type for expanded function ((x$1) => x$1.toString) 我必须指明 callOn(4,(_: Int).toString) 这是相当丑陋的.为什么我的示例不起作用,而集合类上的map,filter,foldLeft等方法似乎不需要这种显式类型? 解决方法
类型推断的技巧是将其视为迭代细化的过程.每个参数块可用于推断一些类型参数,然后可以在后续块中使用.所以采取以下定义:
def chain[T,A,B](x: T)(fn1: T=>A)(fn2: A=>B) = fn2(fn1(x)) 称为: chain(2)(_*10)("xxx"+_) 那么这是怎么推断出来的呢?首先,我们从已知具有Int类型的块(2)开始.将其替换回T参数我们得到: def chain[A,B](x: Int)(fn1: Int=>A)(fn2: A=>B) = fn2(fn1(x)) 下一个参数块是(_ * 10),我们现在知道占位符_的类型是Int …并且将Int乘以Int得到另一个Int.即使发生溢出,返回类型也是如此;在极端,它可能抛出一个异常,但异常的类型为Nothing,它是类型系统中其他所有东西的子类,所以我们仍然可以说Nothing是一个Int,并且推断的Int类型仍然有效. 通过A推断,该方法变为: def chain[B](x: Int)(fn1: Int=>Int)(fn2: Int=>B) = fn2(fn1(x)) 只留下可以从(“xxx”_)推断出的B.由于String Int是一个String,现在的方法是: def chain(x: Int)(fn1: Int=>Int)(fn2: Int=>String) = fn2(fn1(x)) 由于方法的返回类型直接来自fn2,因此也可以明确显示完整性: def chain(x: Int)(fn1: Int=>Int)(fn2: Int=>String): String = fn2(fn1(x)) 你有它,所有类型安全地解决,并证明该方法是静态有效的. 在您的情况下,在可以从类型T => R推断R之前,需要推断类型T.为此,您必须将参数拆分为两个不同的块,以咖喱的形式编写方法: def callOn[T,R](target: T)(f: (T => R)) = f(target) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |