加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

什么时候Scala需要匿名和扩展函数的参数类型?

发布时间:2020-12-16 19:20:28 所属栏目:安全 来源:网络整理
导读:什么时候 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.toStrin
什么时候 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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读