一,声明变量
1,var【变量】:(1)可存放表达式计算结果等 (2)可以后续使用 (3)可以被多次覆盖
2,val【常量】:(1)可存放表达式计算结果等 (2)可以后续使用 (3)不能被改变,如声明错误需重新分配
3,lazy val【惰性常量】:(1)当定义的变量在后续的程序中可能不会被用到时,常用lazy val定义
二,类型体系
AnyVal(值类型)
Numeric types :
Byte |
8位有符号补码整数。数值区间为 -128 到 127 |
Short |
16位有符号补码整数。数值区间为 -32768 到 32767 |
Int(默认) |
32位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long(L) |
64位有符号补码整数。 数值区间为 -9223372036854775808 到 9223372036854775807 |
Float(F) |
32 位, IEEE 754 标准的单精度浮点数 |
Double(默认) |
64 位 IEEE 754 标准的双精度浮点数 |
char 和 boolean :
Char(’ 单引号 ‘) |
16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF |
Boolean |
true或false |
unit :用于函数中无返回值,表示函数有副作用。
AnyRef(引用类型)
All java.* ref type
All scala.* ref type
Null(所有引用类型的最后一个子类)
引用类型为空
Nothing(所有Scala类型的最后一个子类)
程序异常终止,当函数返回Nothing,则表示函数发生异常终止。
三,转义字符
\b |
\u0008 |
退格(BS) ,将当前位置移到前一列 |
\t |
\u0009 |
水平制表(HT) (跳到下一个TAB位置) |
\n |
\u000a |
换行(LF) ,将当前位置移到下一行开头 |
\f |
\u000c |
换页(FF),将当前位置移到下页开头 |
\r |
\u000d |
回车(CR) ,将当前位置移到本行开头 |
\" |
\u0022 |
代表一个双引号(")字符 |
\' |
\u0027 |
代表一个单引号(')字符 |
\\ |
\u005c |
代表一个反斜线字符 '\' |
四,基本操作符
+、-、*、/、%等
&、|、^、>>、<<等
在scala中,这些操作符其实是数据类型的函数,比如1 + 1,可以在scala中,讲+-*/这些运算符也当成了方法
五,语句
1,if :有返回值 ,且返回值可以是混合类型 ,可以返回Unit,最后一行为返回值
2,for :for (i <- 表达式/数组/集合){有返回值}
例:for(i <- 1 to 10) println(i) for(i <- 1 until 10) println(i) for(c <- "Hello World") print(c)
3,while :
4,try :
import java.io.FileNotFoundException import scala.io.Source object Test { def main(args: Array[String]): Unit = { try { lazy val lines = Source.fromFile("Q:\\student1.txt").mkString println(lines) } catch { case e: FileNotFoundException => println("文件找不到") case e:Exception =>("exception") } } }
5,match :
6,Block代码块:用于组织多个表达式,本身也是一个表达式
7,yield :
例:scala> val v = for (i <- 1 to 10) yield i * 10
v: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
8,break :
六,输入输出
输出
1,print:不换行
2,println:换行
3,printf:格式化
另:%s 是一个字符串的占位符 %d 整数的占位符
例:printf("Hi, my name is %s, I'm %d years old.\n", "neo", 30)
输入
1,readLine:从控制台读取用户输入的数据,类似于java中的System.in和Scanner的作用
例:val name = readLine("Welcome to Game House. Please tell me your name: \n")
七,方法和函数
方法:
object Test { def add(a: Int, b: Int): Int = {//固定参数 a + b } def sayHello(name: String, age: Int = 20) {//默认参数,省略返回值类型 print("Hello, " + name + ", your age is " + age) } def sum(nums: Int*): Int = {//变长参数 var res = 0 for (i <- nums) { res += i } res } def main(args: Array[String]): Unit = { val sum = add(10,20) println(sum) sayHello("neo")//默认参数调用 sayHello(age = 30, name = "李四")//带名参数调用 val res = sum(1, 2, 3, 4, 5)//变长参数调用 println(res) val res = sum(1 to 10:_*)//序列调用变长参数 println(res) } }
(1)方法的返回值类型可以不写(Unit可不写),编译器可以自动推断出来,但是对于递归方法,必须指定返回类型
(2)在如果想要将一个已有的序列直接调用变长参数函数,是不对的。比如val s = sum(1 to 5)。此时需要使用Scala特殊的语法(1 to 10:_*)将参数定义为序列,让Scala解释器能够识别。这种语法非常有用!一定要好好主意,在spark的源码中大量地使用到了。
(3)
函数
import java.io.FileNotFoundException import scala.io.Source object Test { def m(f: (Int, Int) => Int): Int = { f(20, 10) } def main(args: Array[String]): Unit = { var add = (a: Int, b: Int) => a + b var sub = (a: Int, b: Int) => a - b var res = m(add) println("add:" + res) res = m(sub) println("sub:" + res) } }
区别
方法 def ,函数 var,函数可以作为参数被传递和操作,函数可以作为方法的参数。
转换
方法 ——>函数 :在方法名后面加空格加下划线
scala> def sum(x:Int ,y:Int):Int = x*y
sum: (x: Int, y: Int)Int
scala> val f1 = sum _
f1: (Int, Int) => Int = <function2>