实际上Scala没有操作符, 只是以操作符的格式使用方法.

操作符的优先级取决于第一个字符(除了赋值操作符), 而结合性取决于最后一个字符

Scala的操作符命名更加灵活:)

操作符

中置操作符(Infix)

a 操作符 b

上述操作符代表一个带有两个参数的方法(一个隐式参数和一个显示参数)

1 to 10  即 1.to(10) Range
1 -> 10 即 1.->(10) 对偶操作符(1, 10)

在自己的类中定义操作符很简单, 以你自己想要做操作符的标识符来定义一个方法就好了.

class MyOperator(factor1: Int) {

    def &@(factor2: Int) = {
new MyOperator(factor2 * factor1)
}
override def toString: String = " " + factor1
} object TestMyOp extends App {
val multi = new MyOperator(4)
println(multi.&@(2))
}
/*output
8
*/

一元操作符

后置操作符: 操作符出现在参数之后

a 操作符
1 toString 即 1.toString()

前置操作符: 出现在参数之前

+, -, !, ~ 可以作为前置操作符, 它们被转化为名为 unary_ 的操作符的方法调用

-a, 即 a.unary_-

赋值操作符

形式为

a 操作符= b  即, a = a 操作符 b
如 a += b 即: a = a + b

技术细节注意一下:

  • <=, >=, != 不是赋值操作符
  • =开头的操作符不是赋值操作符(==, ===, =/=等)
  • 如果a有一个名为操作符=的方法, 那么该方法会被直接调用, 而不是执行赋值操作

操作符优先级

由于Scala可以任意定义操作符, 他需要一套优先级判定方案;

对所有的操作符生效, 同时保留人们熟悉的标准操作符的优先顺序

除了赋值操作符之外, 优先级由操作符的首字符决定, 比方说操作符以*开头优先级高于+开头的;

以下是操作符的首字符的优先级, 从上到下, 优先级依次降低

首字符优先级
* / %
+ -
:
< >
! =
&
^
|
非以上操作符

  • 最低优先级的操作符为赋值操作符
  • 出现在同一行的字符所产生的操作符有优先级相同, 比如说 + 和 -> 有着相同的优先级
  • 后置操作符的优先级低于中置操作符

操作符结合性

当有一系列的相同优先级的操作符时,操作符的结合性决定了它们从左到右求值还是从右到左求值.

在Scala中操作符都是左结合的, 除了:

  • 以冒号:结尾的操作符
  • 赋值操作符

右结合的二元操作符是第二个参数的函数

2 :: Nil 即 Nil.::(2)

apply, update方法

f(arg1, arg2, ...)

如果f不是一个函数或者方法, 那么这个表达式等同于调用apply方法, 除非它出现在赋值语句的左侧, 即 f(arg1, arg2, ...) = value, 则调用的是update方法

f.apply(arg1, arg2, ...)

f.update(arg1, arg2, ..., value)

这机制被用于数组和映射, apply方法常用于伴生对象中, 用来构造对象而不用显式的使用 new 关键字

val happy = new scala.collection.mutable.HashMap[String, Int]
happy("smile") = 10 // happy.update("smile", 10)
happy("smile") // happy.apply("smile")

提取器

所谓提取器就是一个带有 unapply 方法的对象, 你可以把unapply 方法当成伴生对象中 apply 方法的反向应用, apply 方法接受构造参数, 然后将他们变成对象; 而unapply接受一个对象, 然后从中提取值---这些值就是当时用来构造对象的值.

每个样例类都自动具备apply和unapply方法

通常而言, 模式匹配可能会失败, 因此采用 Option 类型作为 unapply 返回值

object Name extends App{

    val me = "wang bin"
val Name(first, last) = me
println(first + " " + last)
println(first) def unapply(input: String): Option[(String, String)] = {
val pos = input.indexOf(" ")
if (pos == -1) None
else Some((input.substring(0, pos), input.substring(pos + 1)))
}
}

带单个参数或者无参数的构造器

在 Scala 中没有只有一个元素的元组, 如果 unapply 要提取单值, 则它应该返回一个目标类型的 Option[A], 比如下面的 Option[Int]

object Number extends  App {

    val Number(digit) = "1111 "
println(digit) def unapply(input: String): Option[Int] = {
try {
Some(Integer.parseInt(input.trim))
} catch {
case ex: NumberFormatException => None
}
}
}

提取器也可以只是测试其输入而不将值提取出来, 这样的话, unapply 方法应该返回 Boolean. 例如:

object IsCompound extends App{
println(NameRes("wang bin"))
println(NameRes("tom hanks ming")) def unapply(arg: String):Boolean = arg.contains(" ")
def NameRes(name: String) = name match {
// @ IsCompound() ()不能丢 测试的是 last 是否包含空格
case Name(first, last @ IsCompound()) => first
case Name(first, last ) => last
}
} /*output
bin
tom
*/

unapplySeq 方法

要提取任意长度的值的序列, 我们应该用 unapplySeq 来命名我们的方法, 它返回值为 Option[Seq[A]], 其中 A 是被提取值的类型. 举例来说 Name 提取器可以产出名字中所有组成部分的序列, 这样一来就可以提取任意数量的变量了

object Name extends App{

    val name = "tom li hi"
println(NameSeq("happy smile")) // 输出: happly
println(NameSeq("tom hanks ming toylor")) // 输出 ming def NameSeq(name: String) = name match {
// @ IsCompound() ()不能丢 测试的是 last 是否包含空格
case Name(first, last) => first
case Name(first, "good", last ) => last
case Name(first, nd, rd, _*) => rd
case _ => "NameSeq"
} def unapplySeq(input: String): Option[Seq[String]] = {
if (input.trim == "") None else Some(input.split("\\s+"))
}
}





Scala 操作符与提取器的更多相关文章

  1. Scala学习笔记--提取器unapply

    提取器就是一个带有unapply方法的对象.你可以把unapply方法当做是伴生对象中apply方法的反向操作. apply方法接收构造参数,然后将他们变成对象. 而unapply方法接受一个对象,然 ...

  2. Scala 深入浅出实战经典 第77讲:模式匹配下的提取器动手构造实战

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  3. Scala:提取器(Extractor)

    http://blog.csdn.net/pipisorry/article/details/52902671 提取器是从传递给它的对象中提取出构造该对象的参数. Scala 标准库包含了一些预定义的 ...

  4. Scala高手实战****第20课:Scala提取器、注解深度实战详解及Spark源码鉴赏

    Spark中的源码的提取器和注解 @SparkContext.scala @ volatile 线程专用 保证线程间共享内容的一致性 @volatile private var _dagSchedul ...

  5. Scala词法文法解析器 (二)分析C++类的声明

    最近一直在学习Scala语言,偶然发现其Parser模块功能强大,乃为BNF而设计.啥是BNF,读大学的时候在课本上见过,那时候只觉得这个东西太深奥.没想到所有的计算机语言都是基于BNF而定义的一套规 ...

  6. jmeter - 关联之正则表达式提取器

    如果有这样的情况:一个完整的操作流程,需要先完成某个操作,获得某个值或数据信息,然后才能进行下一步的操作(也就是常说的关联/将上一个请求的响应结果作为下一个请求的参数): 在jmeter中,可以利用正 ...

  7. jmeter(十二)关联之正则表达式提取器

    如果有这样的情况:一个完整的操作流程,需要先完成某个操作,获得某个值或数据信息,然后才能进行下一步的操作(也就是常说的关联/将上一个请求的响应结果作为下一个请求的参数): 在jmeter中,可以利用正 ...

  8. <转>jmeter(十二)关联之正则表达式提取器

    本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...

  9. Jmeter(五)关联之正则表达式提取器

    我们在用Jmeter做接口或者性能测试时,经常会碰到第二个请求提交的的参数要从第一个请求返回的参数中获取,而这些参数值并不是固定的,是动态变化的,这种场景就要用到关联 Jmeter提供了一种叫做正则提 ...

随机推荐

  1. angular+ionic+cordova(实战项目开发中,持续更新自己学到的和遇到的)

    最近公司开始准备做app了,大佬选择了angular+ionic+corvoda的开发结构,但是对于刚刚才开始对angular才有一点点感觉的我,就像是被一击闷棍敲了,半天没反应过来,emmm,怎么办 ...

  2. 封装好的MD5加密

    /** * 不可逆加密类 为密码提供不可逆的加密运算,使用MD5算法 * * 使用方法: MD5 encrypt = new MD5(); encrypt.getMD5ofStr(str); //返回 ...

  3. windows下的react-native 开发环境搭建

    本教程用安卓手机作为演示. 首先安装jdk.本教程基于jdk1.8,安装时有一点要特别注意:jdk和jre必须装到不同目录下,否则初始化react-native项目时大概率报tools.jar not ...

  4. python实现一般最小二乘系统辨识方法

    问题: 对于一个未知参数的系统,往往需要用到系统辨识的方法,例如对于一个单输入单输出系统: Z(k)+a1*Z(k-1)+a2*Z(k-2)=b1*U(k-1)+b2*U(k-2)+V(k) 其中:V ...

  5. Google Chrome Plus——绿色便携多功能谷歌浏览器

    我更新浏览器的时候一般没有时间更新这个帖子,所以具体请看我网盘下载链接里面的更新日志,请自行查看最新版本下载,谢谢. 近期更新日期:2016.8.15(此时间可能不是最新,请看我网盘里面的更新日志) ...

  6. 关于slmgr命令

    需要管理员的权限运行.这个命令可以用来卸载系统的序列号.使系统处于未激活状态.

  7. SpringBoot就是这么简单

    一.SpringBoot入门 今天在慕课网中看见了Spring Boot这么一个教程,这个Spring Boot作为JavaWeb的学习者肯定至少会听过,但我是不知道他是什么玩意. 只是大概了解过他是 ...

  8. SignalR Self Host+MVC等多端消息推送服务(3)

    一.概述 最近项目确实太忙,而且身体也有点不舒服,慢性咽炎犯了,昨晚睡觉时喘不过气来,一直没休息好,也没什么时间写博客,今天朋友问我什么时候能出web端的消息发送的文章时,我还在忙着改项目的事,趁着中 ...

  9. Javascript 基础知识2017-03-17

    JavaScript语法 1.单行注释:// 多行注释:*/ 2.基本数据类型:            int 整数型   (不等于四舍五入,把小数舍去)            string 字符型  ...

  10. nginx里的sticky的作用

    1.Sticky工作原理 : Sticky是nginx的一个模块,它是基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识 ...