scala偏函数

object CaseTest {
  def main(args:Array[String]){
    println(List(1,3,5,"seven") map{case i:Int =>i+1})
  }
}

运行结果:
Exception in thread "main" scala.MatchError: seven (of class java.lang.String)
    at CaseTest$.$anonfun$main$1(CaseTest.scala:5)
    at CaseTest$.$anonfun$main$1$adapted(CaseTest.scala:5)
    at scala.collection.immutable.List.map(List.scala:287)
    at CaseTest$.main(CaseTest.scala:5)
    at CaseTest.main(CaseTest.scala)

重新修改代码:
println(List(1,3,5,"seven") collect{case i:Int => i+1})  
再次执行结果如下:
List(2, 4, 6)
为什么将map换成了collect之后就可以成功执行呢?这是因为map函数接受一个普通的匿名函数,当适用于"seven"元素时出现类型匹配错误,而collect接受一个偏函数PartialFunction。case语句在scala中除了可以被编译为匿名函数外,还可以编译为一个偏函数PartialFunction,上面程序中编译为了PartialFunction.由上面执行的结果来分析:偏函数它只对会作用于指定类型的参数或指定范围的参数实施作用,超出它的界定范围之外的参数类型和值它会忽略。通过查看scala中的map和collect的源代码可以看到:
final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = {....}

final override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That]): That = {...}

trait PartialFunction[-A, +B] extends (A => B) { self =>      //看不懂源代码中的这一行中的self =>???????也看不懂[-A,+B]?????
  import PartialFunction._   

  def isDefinedAt(x: A): Boolean

  def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] =
    new OrElse[A1, B1] (this, that)
  //TODO: why not overload it with orElse(that: F1): F1?

  override def andThen[C](k: B => C): PartialFunction[A, C] =
    new AndThen[A, B, C] (this, k)

  def lift: A => Option[B] = new Lifted(this)

  def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
    if (isDefinedAt(x)) apply(x) else default(x)

  def runWith[U](action: B => U): A => Boolean = { x =>
    val z = applyOrElse(x, checkFallback[B])
    if (!fallbackOccurred(z)) { action(z); true } else false
  }
}
 

转载于:https://my.oschina.net/u/2963604/blog/1812174

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值