Unapply的构思是由Miles Sabin创造的。 Unapply trait 如下:scalaz/Unapply.scala trait Unapply[TC[_[_]], MA] { /** The type constructor */ 当我看到用Unapply使Int这样的简单类型也能转换成M[A]时觉得挺新鲜。 从Unapply源代码里查了一下,找到了这段: sealed trait Unapply_4 { // /** Unpack a value of type `A0` into type `[a]A0 那么在Unapply里有没有适合的款式呢?
Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。 方法 : " + unapply("Zara@gmail.com")); println ("Unapply 方法 : " + unapply("Zara Ali")); } 方法 : Some((Zara,gmail.com)) Unapply 方法 : None 以上对象定义了两个方法: apply 和 unapply 方法。 unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。 实例中我们使用 Unapply 方法从对象中提取用户名和邮件地址的后缀。 实例中 unapply 方法在传入的字符串不是邮箱地址时返回 None。
提取器 所谓提取器就是一个带有 unapply 方法的对象.可以把 unapply 方法理解为伴生对象中 apply 方法的反向操作. apply 方法接受构造参数,然后将他们变成对象.而 unapply 通常而言,模式匹配可能会失败,因此 unapply 方法返回的是一个Option.它包含一个元组,每个匹配到的变量各有一个值与之对应.下面中返回一个 Option[(Int, Int)] class 互为反向,但不一定总是互为反向.我们可以用提取器从任何类型的对象中提取信息.例如我们可以从字符串中提取名字和姓氏: // 提取器 object Name{ def unapply(input 带单个参数或无参数的提取器 在Scala中,并没有只带一个组件的元组.如果 unapply 方法要提取单值,则应该返回一个目标类型的 Option: object Number { def unapply 方法返回Boolean: object IsContainZero{ def unapply(input: String) = input.contains("0") } 4. unapplySeq
伴生对象中,还有一个unapply方法。与apply相反,unapply是将该类的对象,拆解为一个个的元素。 要实现一个类的提取器,只需要在该类的伴生对象中实现一个unapply方法即可。 object Student { def apply(name:String, age:Int): Student = new Student(name, age) // 实现一个解构器 def unapply name, age) => println(s"姓名:$name 年龄:$age") case _ => println("未匹配") } } } 样例类自动实现了apply、unapply
答案是: 不可以的 要想支持模式匹配,必须要实现一个提取器 [NOTE] 样例类自动实现了apply、unapply方法 定义提取器 之前我们学习过了,实现一个类的伴生对象中的 伴生对象中,还有一个unapply方法。与apply相反,unapply是将该类的对象,拆解为一个个的元素。 ? ? 要实现一个类的提取器,只需要在该类的伴生对象中实现一个unapply方法即可。 语法格式 ? 实现unapply方法来定义提取器 object Student { def unapply(student: Student): Option[(String, Int)] =
提取器 // 提取器是一个带有unapply方法的对象 def apply(user : String, domain : String) = { user + "@" + domain } def unapply(email : String) : Option[(String, String)] = { ("michael@csdn.net")) // Some((michael,csdn.net)) println(unapply("michael csdn")) // None object 将自动执行 case myExtractor(num) => println(x, num) // 自动调用 unapply (10,5) case _ => println("无法计算") } } def apply(x : Int) = { x*2 } def unapply(z :
. */ def liftFU[MA](value: => MA)(implicit MA: Unapply[Functor, MA]): Free[MA.M, MA.A] = liftF( ], A](s: S[A]): FreeC[S, A] = liftFU(Coyoneda lift s) Coyoneda lift s 返回结果Coyoneda[S,A], liftFU用Unapply 看看Unapply这段: /**Unpack a value of type `M0[A0, B0]` into types `[a]M0[a, B0]` and `A`, given an instance [TC, M0[A0, B0]] { type M[X] = M0[X, B0] type A = A0 } = new Unapply[TC, M0[A0, B0]] { [TC, M0[A0, B0]] { type M[X] = M0[A0, X] type A = B0 } = new Unapply[TC, M0[A0, B0]] {
方法(对象提取器),student 作为 unapply 方法的参数,unapply 方法将 student 对象的 name 和 age 属性提取出来,与 Student("alice", 15 )) 中的属性值进行匹配 case 中对象的 unapply 方法(提取器)返回 Some,且所有属性均一致,才算匹配成功, 属性不一致,或返回 None,则匹配失败。 若只提取对象的一个属性,则提取器为 unapply(obj:Obj):Option[T] 若提取对象的多个属性,则提取器为 unapply(obj:Obj):Option[(T1,T2,T3…)] 若提取对象的可变个属性 样例类仍然是类,和普通类相比,只是其自动生成了伴生对象,并且伴生对象中自动提供了一些常用的方法,如 apply、unapply、toString、equals、hashCode 和 copy。 样例类是为模式匹配而优化的类,因为其默认提供了 unapply 方法,因此,样例类可以直接使用模式匹配,而无需自己实现 unapply 方法。
如果Person是个case class,那么Person.tupled和Person.unapply就是它自备的转换函数,我们可以用case class来构建MappedProjection: 1 Int) 2 3 val qYear = for { 4 p <- hlistPerson 5 } yield ((p.name, p.age) <> (YR.tupled,YR.unapply ]("id") 4 def title = column[String]("title") 5 def * = (id,title) <> (Title.tupled,Title.unapply t <- personTitle if p.id === t.id 23 } yield ((p.id,p.name,t.title) <> (Titles.tupled,Titles.unapply "id") 89 def title = column[String]("title") 90 def * = (id,title) <> (Title.tupled,Title.unapply
Unit = { val o1=Demo02('男') o1.info() // 姓名:富贵,年龄:20 } 根据你的业务,可以配置更多apply() 除了 apply 还有一个 unapply apply和unapply 属于Scala的一种语法糖,在class的伴生对象里面定义,apply方法的主要作用可以像调用方法一样创建对象,而unapply方法主要作用是和match一起使用,
Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。 方法 : " + unapply("Zara@gmail.com")); println ("Unapply 方法 : " + unapply("Zara Ali")); } // unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。 就像我们之前提到过的,unapply 用于提取我们指定查找的值,它与 apply 的操作相反。 //unapply 被调用 case _ => println("无法计算") } } def apply(x: Int) = x*2 def unapply(z:
case类本来设计用来进行模式匹配,自带apply和unapply方法,实例化时可以不用new关键字。除了做了优化用于模式匹配,其它方面和普通类没有什么区别。 1,java风格 ? ? ? 二十五,apply,unapply和update 当把对一个对象当做函数使用时,会自动调用它的apply方法。 unapply方法是apply方法的逆方法,我们一般用它来从对象中反推得到其构造参数。 unapply方法通常在模式匹配中会自动被使用。 case类内部实现了apply方法和unapply方法。 当把一个对象当做容器取其某个元素赋值时,会自动调用它的update方法。 1,内部范例 ? ? 2,apply使用演示 ? 3,unapply使用演示 ? ? 二十六,Scala语言的设计哲学 1,一切皆对象 从整数,字符串,函数,类到各种数据结构,Scala中一切皆为对象,Any是它们的超类。
p.copy(firstname = "Michele", birthYear = 1972) p_3: Person = Person(Lacava,Michele,1972) 由于编译器实现了 unapply class 没有参数的时候,你是在使用 case object 而不是一个空参数列表的 case class scala> classMath( A ) A(100) 除了在模式匹配中使用之外,unapply 实例中解构并提取出 tuple 对象 scala> val transform: Person => Option[ (String, String, Int) ] = { | Person.unapply
模式匹配支持伴生对象中自动创建unapply方法。这是样例类最重要的特性,使其能无缝用于模式匹配。自动方法实现实现了合理的toString,equals,hashCode方法。 方法创建新实例valolderAlice=alice.copy(age=31)println(olderAlice)//输出:Person(Alice,31)2.3样例类中的默认方法如上表所示,apply,unapply 题目十二:unapply方法的作用样例类自动生成的unapply方法最主要的用途是什么?题目十三:样例对象与样例类的区别caseclass和caseobject最根本的区别是什么? 答案十二:unapply方法最主要的用途是支持模式匹配。解析:它允许样例类实例被“解构”,即在case语句中提取出其构造器参数。
case类本来设计用来进行模式匹配,自带apply和unapply方法,实例化时可以不用new关键字。除了做了优化用于模式匹配,其它方面和普通类没有什么区别。 1,java风格 ? ? ? 二十五,apply,unapply和update 当把对一个对象当做函数使用时,会自动调用它的apply方法。 unapply方法是apply方法的逆方法,我们一般用它来从对象中反推得到其构造参数。 unapply方法通常在模式匹配中会自动被使用。 case类内部实现了apply方法和unapply方法。 当把一个对象当做容器取其某个元素赋值时,会自动调用它的update方法。 1,内部范例 ? ? 2,apply使用演示 ? 3,unapply使用演示 ? ? 二十六,Scala语言的设计哲学 1,一切皆对象 从整数,字符串,函数,类到各种数据结构,Scala中一切皆为对象,Any是它们的超类。
这是由于模式匹配中的unapply必须在一个extractor object内,所以usr是个object。我们知道一个object加上它的apply可以当作method来调用。 (u: User): Any = macro UserMacros.uapl 5 } 6 } 通过Def Macros在编译过程中自动生成apply和unapply,它们分别对应了函数调用: $qdef 30 } 31 def unapply(u: User) = new Matcher(u) 32 }.unapply($u) 33 ) { 14 object usr { 15 def apply(args: String*): Any = macro UserMacros.appl 16 def unapply $qdef 55 } 56 def unapply(u: User) = new Matcher(u) 57 }.unapply($u) 58
方法(对象提取器) 3) number 会被 传递给 def unapply(z: Double) 的 z 形参 4) 如果返回的是 Some 集合,则 unapply 提取器返回的结果会返回给 n 这个形参 5) case 中对象的 unapply 方法(提取器)返回 some 集合则为匹配成功 6) 返回 None 集合则为匹配失败 scala def main(args: Array[String 把 number 传递给 Square unapply(z: Double) 的 z //3. unapply 被调用,返回一个结果, 返回的结果和程序员的逻辑代码,比如 Some(math.sqrt ("unapply 被调用 z =" + z) // 36.0 Some(math.sqrt(z)) // Some(6.0) } def apply(z: Double): Double 6) 提供 unapply 方法让模式匹配可以工作。 7) 将自动生成 toString、equals、hashCode 和 copy 方法(有点类似模板类,直接给生成,供程序员使用)。
伴生对象有一个apply()用于构造对象,跟apply()对偶的是unapply()用于提取和“解构”。上面例子的匹配,就是用了Person.unapply(...)。 Person类是case class,创建时就帮我们实现了一个伴生对象,这个伴生对象里定义了apply()和unapply()。 比如"(S|s)cala".r有一个unapply()方法,它返回Option[String]。 另一方面"(S|s)(cala)".r的unapply会返回Option[String,String]。
模式匹配支持 伴生对象中自动创建 unapply 方法。 这是样例类最重要的特性,使其能无缝用于模式匹配。 自动方法实现 实现了合理的 toString, equals, hashCode 方法。 olderAlice = alice.copy(age = 31) println(olderAlice) // 输出: Person(Alice,31) 2.3 样例类中的默认方法 如上表所示,apply, unapply 题目十二:unapply 方法的作用 样例类自动生成的 unapply 方法最主要的用途是什么? 答案十二: unapply 方法最主要的用途是支持模式匹配 。 解析: 它允许样例类实例被“解构”,即在 case 语句中提取出其构造器参数。
case类本来设计用来进行模式匹配,自带apply和unapply方法,实例化时可以不用new关键字。除了做了优化用于模式匹配,其它方面和普通类没有什么区别。 1,java风格 ? ? ? 二十五,apply,unapply和update 当把对一个对象当做函数使用时,会自动调用它的apply方法。 unapply方法是apply方法的逆方法,我们一般用它来从对象中反推得到其构造参数。 unapply方法通常在模式匹配中会自动被使用。 case类内部实现了apply方法和unapply方法。 当把一个对象当做容器取其某个元素赋值时,会自动调用它的update方法。 1,内部范例 ? ? 2,apply使用演示 ? 3,unapply使用演示 ? ? 二十六,Scala语言的设计哲学 1,一切皆对象 从整数,字符串,函数,类到各种数据结构,Scala中一切皆为对象,Any是它们的超类。