risc-v中文社区

 找回密码
 立即注册
查看: 1164|回复: 1

[原创] risc-v开发基础 Scala 偏函数进行“偏”处理的实验---(25)

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-26 16:25:06 | 显示全部楼层 |阅读模式
在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 ....

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-26 16:44:03 | 显示全部楼层
def pp(a:Int,bartialFunction[Int,String]) = {
  if(b.isDefinedAt(a)) b(a)
  else "null value"
}
val ppv = pp(2,pint)
println(ppv)
显示:
null value


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-30 08:32 , Processed in 0.030545 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表