1.31

特殊方法 apply/unapply/unapplySeq/update

形式x(...)相当于调用apply()方法;用于赋值等号左侧时,形如x(...)=y,相当于调用update(..., y)

伴生对象的apply方法多用于提供伴生类实例,省去new操作符。

unapply有逆apply之语义,但更广泛,是一种抽取行为(extract),定义了如何从一个量中抽取出若干个量。

unapply方法可定义在scala object或class中,捕获抽取出的量的形式为ObjectName(varName1,...)classInstance(varName1,...),unapply需返回Option,Option[Type]的类型参数Type即是捕获变量的类型,返回元组时允许捕获多个变量(和元组元素个数相同,编译期固定),unapplySeq返回Option[Seq[Type]]允许返回序列,允许动态(运行时)捕获多个量。

对于scala object定义unapply/unapplySeq情形主要提醒的一点是,并不要求该object有伴生class,捕获变量时当然也没有任何构造函数被调用。

class XYPoint(x:Int, y:Int){
}
object XYPoint{
    def unapply(p:XYPoint)= /*if ... None else */ Some((p.x, p.y))
}

object Point {  // no companion class, not to mention the constructor Point(Int,Int)
    def unapply(s:String)=Try(s.split(",")).filter(_.length==2).map(x=>(x(0),x(1))).toOption
}

objects Names{ // no companion class
    def unapplySeq(s:String)=Some(s.split(","))
}

object app extends App {
    val p=new XYPoint(1,2)   // or XYPoint(1,2) if apply defined in companion object
    val (x,y)=p     // yield variables x = p.x, y = p.y
    
    val Point(a,b)="50,100"  // a=50, b=100, Note: no class Point, not to mention the constructor Point(Int,Int)
    
    val s=scala.io.StdIn.readLine
    s match {
        case Names(n1) => ...  // a name, no ','
        case Nmaes(n1, n2) => ... // two names separated by ','
        case Names(n1,n2,n3)=>....
    }
}

对于抽取器用于变量声明时,如果返回None会导致运行时抛出Error,如果用于match,表示匹配不上该case。

case class自动具备apply、unapply。

posted @   秋渡晚枫  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示