scala学习笔记(四)样本类与模式匹配
访问修饰符
格式:private[x]或protected[x],x指某个所属包、类或单例对象,表示被修饰的类(或方法、单例对象),在X域中公开,在x域范围内都可以访问;
private[包名]:在该包名作用域内,被修饰域都能被访问;
private[类名]:在该类的作用域,被修饰域都能被访问;
private[this]:仅能在包含了定义的同一对象中访问,用于保证同一类中不能被其它对象访问;
例子:
package tests{
private[tests] class Test{
private[tests] def showTest=println("start showTest Runing !")
}
package units{
object unit{
def main(args:Array[String]){
val a = new Test
a.showTest
}
}
}
}
样本类
定义:带有case修饰符的类称为样本类(case class);
例如:
case class Unit(name:String)
val t = Unit(“123)
scala为样本类提供的便捷特点:
1、添加了与类名相同的工厂方法,也就是说可以用Unit(“123”)替换new Unit(“123”)构造对象;
2、样本类参数列表中的所有参数隐式获得了val前缀,被当作字段维护,如:t.name;
3、编译器为类添加了方法toString、hashCode和equals的实现;
模式匹配
一个模式匹配包含了一系列备选项,以case关键字开始,每个备选项都包含了一个模式及一到多个表达式,他们在模式匹配过程中被计算,箭头符号=>隔开了模式和表达式;
格式:选择器 match {备选项}
备选项格式:case 模式 => 表达式
match与switch比较:
1、match 是scala表达式,始终以值做为结果;
2、备选项永远不会掉到下一个case执行;
3、如果没有模式匹配到,将抛出MatchError异常;
模式的种类
通配模式:能匹配任意对象,如:case _ => todo
常量模式:任何字面量、val、单例对象(Nil)都可以做为常量,仅能匹配自身,如:def fun(x:Any) = x match {case Nil => “123”;case _ => “456”};
变量模式:类似通配符,可以匹配任意对象,与通配模式不同的是,它会把变量绑定在匹配的对象上,因此之后可以使用这个变量操作对象;
如:
scala> var p = "123456"
p: String = 123456
scala> def fun(x:Any) = x match {
| case p => println("fun result is :"+p)
| }
fun: (x: Any)Unit
scala> fun("hello world")
fun result is :hello world
说明:
1、scala中小写字母开始的简单名被当作是模式变量,所有其它的引用被认为是常量。
2、以反引号包住变量名表示是常量;
构造器模式
假如模式指定为一个样本类,那么这个模式就表示首先检查对象是该名称的样本类成员,然后检查对象的构造参数是否符号额外提供的模式,该模式使scala支持深度匹配;
例子:
scala> case class Unit(x:String){
| def showUnit=println("showUnit " + x);
| }
defined class Unit
scala> def fun(x:Any) = x match {
| case Unit("123") => println("123456")
| case _ => println("no match")
| }
fun: (x: Any)Unit
scala> fun(new Unit("234"))
no match
scala> fun (new Unit("123"))
123456
序列模式
匹配List或Array这样的序列类型,同样的语法也可以指定模式内任意数量的元素;
如:
scala> def fun (x:Any)= x match{
| case List(0,_,_) => println("123")
| case _ => println("no match")
| }
fun: (x: Any)Unit
scala> fun(List(1,2,3))
no match
说明:匹配一个不指定长度的序列可以 _*做为模式的最后元素,如:List(0,_*);
元组模式
用于匹配元素,类似(a,b,c)这样的模式可以匹配任意的三元组;
如:
scala> def fun(x:Any) = x match {
| case ("123",1,2) => println("123")
| case _ => println("no match")
| }
fun: (x: Any)Unit
scala> fun((1,2,3))
no match
scala> fun(("123",1,2))
123
类型模式
可把类型模式当作类型测试和类型转化的简易替代;
如:
scala> def fun(x:Any) = x match {
| case s:String => println("String Type length is" + s.length)
| case _ => println("no match")
| }
fun: (x: Any)Unit
scala> fun("123456")
String Type length is6
说明:
1、与该模式功能相同的还有两个函数 isInstanceof(类型测试)与 asInstanceof(类型转换)
2、x.isInstanceof[String]检查x是否为String类型类型,是就返回true否则返回false;
3、x.asInstanceof[String]将x转换为String类型返回;
4、类型擦除:类型参数信息没有保留到运行期,因此,运行期没有办法判定给定的Map对象创建时带了两个Int参数还是其它的类型,,系统只能判定这个值是某种任意类型参数的Map,而唯一例外的数组类型Array[类型];
变量绑定模式
除了独立的变量模式外,可使用该模式对任何其它模式添加变量,格式:变量名+@+模式,这种模式的意义在于它能像通常的那要做模式匹配,并且如果匹配成功,则把变量设置成匹配的对象;
例子:
scala> case class Unit(a:Int,b:String){
| def showUnit=println("a:"+a+",b:"+b)
| }
defined class Unit
scala> def fun(x:Any)= x match {
| case Unit(1,e @ "123") => println("e:"+e)
| case _ => println("No Match")
| }
fun: (x: Any)Unit
scala> fun(Unit(1,"123"))
e:123
scala> fun(Unit(1,"234"))
No Match
模式守卫
scala要求模式是线性的:模式变量仅允许在模式中出现一次,不过可以使用模式守卫重新指定该匹配规则;
模式守卫接在模式之后,开始于if,守卫可以是任意的引用模式中变量的布尔表达式,如果存在模式守卫,那么只有在守卫返回true的时候匹配才成功。
例子:
scala> def fun(x:Any)=x match {
| case i:Int if i>0 => println("i>0")
| case s:String if s.length ==3 => println("type is String")
| case _ => println("No Match")
| }
fun: (x: Any)Unit
scala> fun(123)
i>0
scala> fun("123")
type is String
scala> fun(-1)
No Match
模式重叠
模式以代码编写的先后次序尝试执行,很重要的一点是,全匹配的样本要跟在具体的简化方法之后,如果写成其它次序,那么全匹配样本将比特定规则样本得到更高的优先级,这种情况下,编译器将在你做这种尝试时发出警告,因为特定规则的样本没有可能执行;
封闭类
功能:scala编译器帮助检查match表达式中遗漏的模式组合。
原理:让样本类的超类被封闭,封闭类除了类定义所在的文件外不能再添加任何新的子类,而仅需要关系所定义的子类。当使用封闭类的样本类进行模式比配时,编译器会自动检查是否存在缺失的模式组合,存在时将抛出警告;
例子:
scala> sealed abstract class Unit
defined class Unit
scala> case class U1(s:String) extends Unit
defined class U1
scala> case class U2(i:Int) extends Unit
defined class U2
scala> case class U3(b:Any) extends Unit
defined class U3
scala> def fun(x:Unit) = x match {
| case U1(_) => println("U1")
| case U2(_) => println("U2")
| }
<console>:12: warning: match may not be exhaustive.
It would fail on the following input: U3(_)
使用注解去掉警告:
scala> def fun(x:Unit) = (x: @unchecked) match {
| case U1(_) => println("U1")
| case U2(_) => println("U2")
| }
fun: (x: Unit)Unit
说明:
模式匹配的类层级,都应当使用封闭类,而封闭类的实现把关键字sealed放在最顶层类的前面即可;
Option类型
该类型为一种可选值的定义,有两种形式Some(x),其中x为实际值和None,代表缺省值。可作用于scala集合类的某些标准操作会产生可选值;
例子:
scala> val ss = Map("123"->"Hello","456"->"World")
ss: scala.collection.immutable.Map[String,String] = Map(123 -> Hello, 456 -> Wor
ld)
scala> def fun(x:Option[String])= x match {
| case Some(s) => println(s)
| case None => println("No Match")
| }
fun: (x: Option[String])Unit
scala> fun(ss get "123")
Hello
scala> fun(ss get "567")
No Match
注意:Option[String]与String两种是不同的类型,不能互相赋值;
模式的应用
1、变量的定义
例1:
scala> val aa = (123,"456")
aa: (Int, String) = (123,456)
scala> val (a,b) = aa
a: Int = 123
b: String = 456
scala> println(a)
123
scala> print(b)
456
2、偏函数的样本序列
样本序列就是函数字面量,与通常的函数里子面量不同的是,样本序列可以有多个入口点,每个都有自己的参数列表,每个样本都是函数的一个入口点,参数被模式特化。而通常的函数字面量只有一个入口;
例1(样本序列):
scala> val fun:Option[Int] => Int ={
| case Some(x) => x
| case None => 0
| }
fun: Option[Int] => Int = <function1>
scala> fun(Some(10))
res2: Int = 10
scala> fun(None)
res3: Int = 0
例2(偏函数应用):
scala> val fun:PartialFunction[List[Int],Int] = {
| case x :: y :: _ => y
| }
fun: PartialFunction[List[Int],Int] = <function1>
scala> fun.isDefinedAt(List(5,6,7))
res6: Boolean = true
scala> fun.isDefinedAt(List(2))
res7: Boolean = false
说明:
1、PartialFunction[List[Int],Int]表示仅包含从整数列表到整数的偏函数;
2、fun.isDefinedAt用于检查该偏函数对List(5,6,7)有定义,上例中表示函数对任何有至少两个元素的列表有定义;
scala学习笔记(四)样本类与模式匹配的更多相关文章
- Scala学习文档-样本类与模式匹配(match,case,Option)
样本类:添加了case的类便是样本类.这种修饰符可以让Scala编译器自动为这个类添加一些语法上的便捷设定. //样本类case class //层级包括一个抽象基类Expr和四个子类,每个代表一种表 ...
- [Scala]Scala学习笔记四 类
1. 简单类与无参方法 class Person { var age = 0 // 必须初始化字段 def getAge() = age // 方法默认为公有的 } 备注 在Scala中,类并不声明为 ...
- scala学习笔记(3):类
1 类 (1) scala把主构造函数放到类的定义中,让定义字段及相应方法变得简单起来. class People(age: Int, name: String) scala会自动将这个类变成publ ...
- scala学习笔记2(类,继承,抽象类)
class Person{ // _ 是占位符; var name : String = _ val age : Int = 27 // private[this] 定义的内容无法外部使用,起到保护作 ...
- scala 学习笔记七 基于类型的模式匹配
1.介绍 Scala 提供了强大的模式匹配机制,应用也非常广泛. 一个模式匹配包含了一系列备选项,每个都开始于关键字 case.每个备选项都包含了一个模式及一到多个表达式.箭头符号 => 隔开了 ...
- scala学习笔记:理解类继承
scala> import scala.reflect._ import scala.reflect._ scala> class Person(@BeanProperty var nam ...
- ES6学习笔记四(类和对象)
{ // 构造函数和实例 class Parent{ constructor(name='mukewan'){ this.name=name; } } let v_parent=new Parent( ...
- scala 学习笔记四 匿名函数
1.介绍 Scala 中定义匿名函数的语法很简单,箭头左边是参数列表,右边是函数体. 使用匿名函数后,我们的代码变得更简洁了. 下面的表达式就定义了一个接受一个Int类型输入参数的匿名函数: var ...
- swift学习笔记(四)关于类的继承
在swift中,继承是区分类与其它对象的基本特征 继承后的子类能够重写父类的方法,包含类方法和实例方法,属性和附属脚本(subscript) 在继承过程中,构造器方法init()是不被继承的,须要显示 ...
- Typescript 学习笔记四:回忆ES5 中的类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
随机推荐
- Node.js和MongoDB - MongoJS入门
第一次尝试翻译外国牛人的博文,希望大家喜欢. 本文源码详见:https://github.com/njaulj/mongojs 一点都不夸大的说,近年来node.js和mongodb的确是大放异彩,在 ...
- Be Pythonic ,Google Python Style Guide
为了更规范的写代码,变得更专业 分号 1 不在句末添加分号,不用分号在一行写两句代码 行长度 2 每行不超过80字符,python会隐式行连接圆括号,中括号,花括号中的字符,如多参数方法调用可以写为多 ...
- Custome Buble Data Point
<navigation:Page xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/to ...
- hdu 4542 小明系列故事——未知剩余系
小明系列故事——未知剩余系 题意:操作0表示某数有n个约数,操作1为某数有n个非约数:n <= 47777,若是存在小于2^62的数符合,则输出该数,否则若是不存在输出Illegal,若是大于2 ...
- Call Azure Queue get "The remote server returned an error: (400) Bad Request."
这几天开始研究Windows Azure, 在使用Azure Queue 的时候,CreateInfNotExists 总是抛出异常 "The remote server returned ...
- 【Selenium】自动化调试后C盘越来越大
在本机调试了一段时间自动化脚本后发现C盘占用越来越大,增长速度比较明显 通过360等工具清理系统垃圾表明并不好使 最后在系统临时文件中看到大量因为调试或不正常结束而Driver而产生的临时文件 具体方 ...
- MongoDB 覆盖索引查询
MongoDB 覆盖索引查询 官方的MongoDB的文档中说明,覆盖查询是以下的查询: 所有的查询字段是索引的一部分 所有的查询返回字段在同一个索引中 由于所有出现在查询中的字段是索引的一部分, Mo ...
- C# const和statci readonly区别
1.const 是属于编译时的变量,它定义的常量是在对象初始化时赋值,以后不能改变他的值. 它适用于两种场景:1.取值永久不变(比如圆周率.一天包含的小时数.地球的半径等) 2.对程序性能要求非常苛 ...
- 全国省市级联数据sql语句 mysql版
全国省市级联数据sql语句 mysql版 --省级 provincial create table provincial ( provincialID int, provincialName ), p ...
- jQuery中的一些正则匹配表达式
jQuery常用正则匹配表达式 落雨 //整数 "^-?[1-9]\\d*$", //正整数 "^[1-9]\\d*$", //负整数 intege2: &qu ...