Scala入门笔记二
标识符
可用的字符
- 处理括号类字符,分隔符之外,其他所有的可打印的ASCII字符,如字母,数字,下划线和美元符号($)均可出现在Scala标识符中
- 插入符包括了(,) [,] {,and}
- 分隔符包括 ` ' " . ; ,等
- Scala还允许在标识符中使用编码在 \u0020到\u007F之间的字符,如数学符号,想 / 和 < 这样的操作符字符以及其他的一些符号
不能使用保留字.
普通标识符
- 常见的标识符往往由字母或下划线开头,后面跟着一些字母,数字,下划线和$符
- Scala允许使用Unicode格式的字符
- $符在Scala内部会作为特定作用,尽量不要使用
- Scala编译器会将下划线之后,空格之前的所有字符视为标识符的一部分
- 假如在下划线后输入了操作符,那么不允许在操作符后输入字母或数字
- 假如某一标识符以操作符开头,那么后面的字符也必须是操作符字符
示例
val xyz_++= = 1
使用反引号定义标识符
可以通过反引号定义标识符,两个反引号内的任意长度的字符串便是定义的标识符.
def `test that addition work`= assert(1 + 1 = 2)
无参数方法
- 对于不包含参数的方法,除了可以选择使用中缀调用或后缀调用方式之外,Scala还允许用户灵活决定是否使用括号
- 定义无参方法时省略了括号,那么在调用这些方法时必须省略括号
- 定义无参方法时添加了空括号,那么调用该方法时可以选择省略或保留括号
几个等价表达式
List(1, 2, 3, 4).filter((i: Int) => isEven(i)).foreach((i: Int) => println(i))
List(1, 2, 3, 4).filter(i => isEven(i)).foreach(i => println(i))
List(1, 2, 3, 4).filter(isEven).foreach(println)
List(1, 2, 3, 4) filter isEven foreach println
优先级规则
1. 所有字母
2. |
3. ^
4. &
5. < >
6. = !
7. :
8. + -
9. * / %
10. 其他特殊字符
- 所有操作符都是方法
- 并不是所有方法都是左结合
- 任何名字以冒号(:)结尾的方法均与其右边的对象绑定
cons操作
- cons是constructor的缩写
- cons操作指通过
::
方法将某一元素放置到列表前面
示例
scala> val list = List('c', 'd')
list: List[Char] = List(c, d)
scala> 'a' :: list
res1: List[Char] = List(a, c, d)
scala> val list = List('c', 'd')
list: List[Char] = List(c, d)
scala> 'b' :: list
res2: List[Char] = List(b, c, d)
scala> list.::('a')
res3: List[Char] = List(a, c, d)
scala> 'a' :: list
res4: List[Char] = List(a, c, d)
scala> 'b' :: list
res5: List[Char] = List(b, c, d)
注意:
'a' :: list
等价于list.::('a')
不能使用该方法重复插入多个字符
if语句
Scala的if语句可以向Java中一样使用
if (2 + 2 = 5) {
println("if")
} else if (2 + 2 = 3) {
println("else if")
} else {
println("else")
}
Scala中的if语句是有返回值的. 可以将if表达式的结果值赋值给其他变量. 以下面代码为例.
val configFile = new java.io.File("someFile.txt") val configFilePath = if (configFile.exists()) {
configFile.getAbsolutePath()
} else {
configFile.createNewFile()
configFile.getAbsolutePath()
}
if语句返回值的类型也被称为所有条件分支的最小上界类型,也就是与每条each子句可能返回值类型最接近的父类型.在上面例子中,
configFilePath
是if表达式的结果值,该if表达式将执行文件不存在的条件分支(假定),并返回新创建文件的绝对路径.将if语句的返回值赋予变量configFilePath
.
Scala不支持三元表达式
循环
for推导式
for循环
示例
代码
val list = List("A", "B", "C")
for (item <- list)
println(item)
输出
A
B
C
生成器表达式
- 像
item <- list
这样的表达式被称为生成器表达式 - 该表达式会基于集合生成单独的数值
- 左箭头操作符(<-)用于对象列表这样的集合进行遍历
保护式: 筛选元素
- for语句中可以加入if表达式来筛选元素,这些表达式被称为保护式(guard)
示例
代码
val list = List("ABC", "CDE", "EFG")
for (item <- list
if item.contains("C")
)
println(item)
输出
ABC
CDE
添加多个保护式
示例
val list = List("ABC", "BCD", "CDE")
for (item <- list
if item.contains("B")
if !item.startsWith("A")
)
println(item)
for (item <- list
if item.contains("B") && !item.startsWith("A")
)
println(item)
输出
BCD
BCD
- 分别为两个for循环的输出
Yielding
- 使用
yielding
关键字能在for表达式中生成新的集合
示例
代码
val list = List("ABC", "BCD", "CDE")
val filterItems = for {item <- list
if item.contains("B")
if !item.startsWith("A")
} yield item
filterItems
运行
scala> val list = List("ABC", "BCD", "CDE")
list: List[String] = List(ABC, BCD, CDE)
scala> val filterItems = for {item <- list
| if item.contains("B")
| if !item.startsWith("A")
| } yield item
filterItems: List[String] = List(BCD)
扩展作用域与值定义
- 能够在for表达式中的最初部分定义值,并可在以后的表达式中使用该值
示例
代码
val list = List("abc", "bcd", "cde")
val upcaseItems = for {
item <- list
upcaseItem = item.toUpperCase()
} yield upcaseItem
运行
scala> val list = List("abc", "bcd", "cde")
list: List[String] = List(abc, bcd, cde)
scala>
| val upcaseItems = for {
| item <- list
| upcaseItem = item.toUpperCase()
| } yield upcaseItem
upcaseItems: List[String] = List(ABC, BCD, CDE)
while循环
示例
while (表达式) {
do something
}
do...while循环
示例
var count = 0
do {
count += 1
} while(count < 10)
条件操作符
操作符 | 操作 |
---|---|
&& | 和操作 |
|| | 或操作 |
> | 大于 |
>= | 大于或等于 |
< | 小于 |
<= | 小于或等于 |
== | 等于 |
!= | 不等于 |
&&
和||
是短路操作符在Java中
==
只会对对象引用进行比较, 调用equals
来比较字段值; Scala使用==
符执行逻辑上的相等检查. 即调用equals
方法进行判断.public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
} public boolean equals(Object obj) {
return true;
} public static void main(String args[]) {
Person p1 = new Person("sun", 20);
Person p2 = new Person("li", 20);
System.out.println(p1 == p2);
}
}
// 输出:
false
class Person(var name: String, var age: Int) {
override def equals(obj: scala.Any): Boolean = true
} val p1 = new Person("sun", 20)
val p2 = new Person("sun", 20) println(p1 == p2) // 输出:
true
使用try...catch...final子句
- Scala使用模式匹配来捕获异常, 而Java使用单独的catch子句来捕获各个异常
- 使用
case NonFatal(ex) => ...
子句使用scala.util.control.NonFatal
匹配了所有的非致命性异常 - 通过编写
throw new MyBadException(...)
抛出异常 - 如果自定义异常是一个case类,那么抛出异常时可以省略new关键字
实例
try {
...
} catch {
case NonFatal(ex) => println(s"Non fatal exception! $ex")
case ...
} finally {
...
}
惰性赋值
- 惰性赋值是与传名参数相关的技术
- 如果希望以延迟的方式初始化某值, 并且表达式不会被重复计算, 则需要使用惰性赋值
- 常见应用场景
- 由于表达式执行代价昂贵(比如打开一个数据库连接), 希望能推迟该操作, 直到确实需要表达式结果时才执行它
- 为了缩短模块启动时间, 可以将当前不需要的某些工作推迟执行
- 为了确保对象中其他字段的初始化过程能优先执行, 需要将某些字段惰性化
示例
object ExpensiveResource {
lazy val resource: Int = init()
def init(): Int = {
// 某些代价昂贵的操作
0
}
}
- lazy关键字意味着求值过程会被推迟,只有需要时才会执行计算
- 首次使用惰性值时, 初始化代码才会被执行一次, 这种只能执行一次的计算对于可变字段而言没有任何意义.因此lazy关键字不能修饰var变量
- 通过**保护式来实现惰性值
枚举
- Scala通过在标准库中专门定义Enumeration类实现枚举
示例一
代码
// file: enum.scala
object Breed extends Enumeration {
type Breed = Value
val doberman = Value("Doberman Pinscher")
val yorkie = Value("Yorkshire Terrier")
val scottie = Value("Scottish Terrier")
val dane = Value("Great Dane")
val portie = Value("Portuguese Water Dog")
}
import Breed._
println("ID\tBreed")
for (breed <- Breed.values) println(s"${breed.id}\t$breed")
println("\nJust Terriers:")
Breed.values filter (_.toString.endsWith("Terrier")) foreach println
def isTerrier(b: Breed) = b.toString.endsWith("Terrier")
println("\nJust Terriers:")
Breed.values filter isTerrier foreach println
运行
scala enum.scala
输出
ID Breed
0 Doberman Pinscher
1 Yorkshire Terrier
2 Scottish Terrier
3 Great Dane
4 Portuguese Water Dog
Just Terriers:
Yorkshire Terrier
Scottish Terrier
Just Terriers:
Yorkshire Terrier
Scottish Terrier
可插入字符串
下面是一个简单示例:
val name = "Buck Trends"
println(s"Hello, $name")
格式化
下面是几个对可插入字符串进行格式化的示例.
scala> val gross = 100000F
gross: Float = 100000.0
scala> val net = 64000F
net: Float = 64000.0
scala> val percent = (net / gross) * 100
percent: Float = 64.0
scala> println(f"$$${gross}%.2f vs. $$${net}%.2f or ${percent}%.1f%%")
$100000.00 vs. $64000.00 or 64.0%
scala> val s = "%02d: name = %s".format(5, "Dean Wampler")
s: String = 05: name = Dean Wampler
// 原生插入器
scala> val name = "Dean Wampler"
name: String = Dean Wampler
scala> s"123\n$name\n456"
res1: String =
123
Dean Wampler
456
scala> raw"123\n$name\n456"
res2: String = 123\nDean Wampler\n456
- 使用
$$
打印一个$
- 使用
%%
打印一个%
Scala入门笔记二的更多相关文章
- 大数据入门第二十一天——scala入门(二)并发编程Akka
一.概述 1.什么是akka Akka基于Actor模型,提供了一个用于构建可扩展的(Scalable).弹性的(Resilient).快速响应的(Responsive)应用程序的平台. 更多入门的基 ...
- 大数据入门第二十天——scala入门(二)scala基础02
一. 类.对象.继承.特质 1.类 Scala的类与Java.C++的类比起来更简洁 定义: package com.jiangbei //在Scala中,类并不用声明为public. //Scala ...
- 大数据入门第二十天——scala入门(二)scala基础01
一.基础语法 1.变量类型 // 上表中列出的数据类型都是对象,也就是说scala没有java中的原生类型.在scala是可以对数字等基础类型调用方法的. 2.变量声明——能用val的尽量使用val! ...
- Shader 入门笔记(二) CPU和GPU之间的通信,渲染流水线
渲染流水线 1)应用阶段(CPU处理) 首先,准备好场景数据(摄像机位置,视锥体,模型和光源等) 接着,做粗粒度剔除工作. 最后,设置好每个模型的渲染状态(使用的材质,纹理,shader等) 这一阶段 ...
- scala 学习笔记二 方法与函数
1.介绍 Scala 有方法与函数,二者在语义上的区别很小.Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量.换句话来说在类中定义的函数即是方法. Scala 中的方法跟 Java 的 ...
- [Scala]Scala学习笔记二 数组
1. 定长数组 如果你需要一个长度不变的数组,可以使用Scala中的Array. val nums = new Array[Int](10) // 10个整数的数组 所有元素初始化为0 val str ...
- onethink入门笔记(二)
5.onethink页面端获得后台服务器传值的方法 1:一般后台通过assign的值前台通过{$value}显示出来; 2:如果需要在js中使用 则可以通过 在js中写 var m = "{ ...
- OpenGLES入门笔记二
#import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> #import <OpenGLES/ES2/gl.h& ...
- Redis入门笔记(二)-配置及运行
转自: http://gly199.iteye.com/blog/1056424 1.redis基本参数 redis的配置文件中的常见参数如下: daemonize 是否以后台进程运行,默认为no ...
随机推荐
- Linux的iptables常用配置范例(3)
编辑/etc/rc.local,加入iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j MASQUERADE,外网口eth1为dhc ...
- 酷炫的方块状散点3D
http://threejs.org/examples/webgl_particles_random.html
- [转] Eclipse 使用 Link 方式进行插件的安装
下方来自 http://www.iteye.com/topic/1113353 Eclipse 的插件安装方法一般有以下几种(以安装 SVN 插件为例说明,Eclipse 版本为:3.7/Indigo ...
- 转载:温故而知新 - AngularJS 1.x
原文: http://geek.csdn.net/news/detail/102405 温故而知新 - AngularJS 1.x
- mybatis+spring事务
http://www.mybatis.org/spring/zh/transactions.html 第四章 事务 一个使用 MyBatis-Spring 的主要原因是它允许 MyBatis 参与到 ...
- AppServ设置虚拟主机 及域名连接
1: 安装好AppServ2.5.9软件,官网是:http://www.appservnetwork.com/ ,2.59下载地址是:http://nchc.dl.sourceforge.net/so ...
- 3DTouch简单了解
3D Touch的三大模块 代码Demo:https://github.com/haozheMa/3DTouch 在我们的app中使用3D Touch功能,主要分为以下三个模块: 1.Home Scr ...
- R语言实战(四)回归
本文对应<R语言实战>第8章:回归 回归是一个广义的概念,通指那些用一个或多个预测变量(也称自变量或解释变量)来预测响应变量(也称因变量.效标变量或结果变量)的方法.通常,回归分析可以用来 ...
- iOS tableViewCell plane格式下,接近section边缘不显示分割线却被复用解决办法
今天做公司产品的时候遇到了如题问题,困扰我很长时间,用尽各种办法不能解决,究其原因不知为何,自定义cell低端有view划线的时候,划线一般的显示1像素,而贴着section的显示很少 顶多0.3像素 ...
- UDP网络程序模型设计
UDP网络程序设计 1. UDP网络编程模型程序初始化 1.1服务器使用的函数 创建socket----->socket 绑定地址-------->bind 接受数据--------> ...