|
在chisel开发芯片设计的时候,有配置参数site-here-up机制,需要明白偏函数的作用。
偏函数的具体内容就是要对所有用户输入的数据进入“部分且有选择地”进行处理,这是它
的最终目标。从语法角度来说,
trait PartialFunction[-A,+B] extends (A=>B){ self=>
import PartialFunction._ //导入object PartialFunction中的所有
//也就是说trait中导入同名object中所有东东
//伴生类中不import伴生对象,那么使用伴生对象中的东东时需要用 “伴生对象.xxx"格式
//所以说上面import PartialFunction._主要目的是使用时不要再加PartialFunction.xxx
def isDefinedAt(x:A):Boolean
def orElse[A1<:A,B1>:B](that: PartialFunction[A1,B1]): partialFunction[A,B]=
new OrElse[A1,B1](this,that) //此处orElse其实是同名object PartialFunction中的内部类
...
}
object PartialFunction中:
def appply[A,B](f:A=>B): PartialFunction[a,b] = {case x => f(x)}
我们使用时,可能这样:
//输入Int,但只取值为2/3的,返回对应的字符串
val r: PartialFunction[Int,String] = {
case i if(i == 2 || i == 3) => i.toString
}
//输入List,但只取其中Int元素的值,其它类型的不取,最终返回一个新的List (说明:因为collect的参数也是一个偏函数)
val rl = List(1,2,3,"Hello") collect {
case i:Int => i
}
上面二种是很常见的使用方法,scala编译器会将上面这样的代码解释为一个PartialFunction类型,当然会产生isDefinedAt和apply方法了,
产生的方法举例如下:
def isDefinedAt(x:Int):Boolean = x match {
case i if(i == 2 || i == 3) => true
}
def apply(v1:Int):String = v1 match {
case i if(i == 2 || i == 3) => i.toString
}
也就是说将用户所写的代码直接放入apply中,用户的case语句放入isDefinedAt中,但是返回值换成了true和false而已,
用户使用时:
val res = r(2) 正常
val res = r(0) 异常
val res = if(r.isDefinedAt(0)) r(0) else .... 当然也可以使用OrElse其它方法
当我们使用偏函数对象时其实应该说是定义偏函数时,编译器会将偏函数编译成trait Function1的实现类:
trait Function1[-T1, +R] extends AnyRef { self =>
def apply(v1: T1): R
。。。
}
通过前面所举例子代码,可以看得出来,编译器将用户所写的case语句当作了一个匿名函数,
且这个case语句的参数就是这个Function1的入参,也就是说将用户case语句放入apply中,
改造用户case语句返回值为true/false之后放入isDefinedAt中,用户使用时需要用isDefinedAt
进行判断之后再用apply方法即上面if(r.isDefinedAt(0)) r(0) else ....
|
|