1 import org.junit.Test 2 3 /** 4 * scala的基本数据类型,条件,循环 5 */ 6 class C1_Base { 7 8 @Test 9 def Test1(): Unit = { 10 val name1: String = null 11 println(name1) 12 // Any类是所有类的超类 13 val name2: Any = "leo" 14 println(name2) 15 16 //指定类型:无论声明val变量,还是声明var变量,都可以手动指定其类型,如果不指定的话,scala会自动根据值,进行类型的推断。 17 val name3, name4: String = null 18 val num1, num2 = 100 19 20 //基本数据类型:Byte、Char、Short、Int、Long、Float、Double、Boolean 21 //类型的加强版类型:scala使用很多加强类给数据类型增加了上百种增强的功能或函数。 22 //scala没有基本数据类型与包装类型的概念,统一都是类。scala自己会负责基本数据类型和引用类型的转换操作。 23 println(1.toString()) 24 //1 + 1,可以写做 25 1.+(1) 26 //Scala还提供了RichInt、RichDouble、RichChar等类型,RichInt就提供了to函数 27 // 1.to(10),此处Int先 隐式转换 为RichInt,然后再调用其to函数 28 println(1.to(10)) 29 //又可以写做 30 println(1 to 10) 31 //String类通过StringOps类增强了大量的函数 交集 32 println("Hello".intersect(" World")) 33 34 // (1, 2, 3)的写法定义一个Tuple3 35 println((1, 2, 3).getClass.getSimpleName) 36 } 37 38 @Test 39 def mathTest(): Unit = { 40 import scala.math._; 41 println(sqrt(2)); 42 println(pow(2, 4)); 43 println(min(3, Pi)) 44 } 45 46 @Test 47 def Test2(): Unit = { 48 //如果调用函数时,不需要传递参数,则scala允许调用函数时省略括号 49 println("Hello World".distinct) 50 51 //使用“类名()”的形式,其实就是“类名.apply()”的一种缩写。通常使用这种方式来构造类的对象,而不是使用“new 类名()”的方式。 52 println(Array(1, 2, 3, 4)) //实际上是用Array object的apply()函数来创建Array类的实例 53 println("Hello World"(6)) //获取第6个字母 实际上是"Hello World".apply(6)的缩写 54 } 55 56 @Test 57 def ifTest(): Unit = { 58 //条件 59 //if表达式的定义:在Scala中,if表达式是有值的,就是if或者else中最后一行语句返回的值。 60 val age = 30; 61 //可以将if表达式赋予一个变量 62 val adult = if (age > 18) 1 else 0 63 //if表达式的类型推断:由于if表达式是有值的,而if和else子句的值类型可能不同 64 //Scala会自动进行推断,取两个类型的公共父类型。 65 //Any是String和Int的公共父类型 66 //如果if后面没有跟else,则默认else的值是Unit,也用()表示,类似于java中的void或者null 67 var a, b, c = 0; 68 if (a < 10) { 69 b = b + 1; 70 c = c + 1 71 } 72 val d = if (a < 10) { 73 b = b + 1; 74 c + 1 75 } 76 77 println(adult) 78 println(isAdult(age)) 79 println(a + " " + b + " " + c + " " + d) 80 } 81 82 def isAdult(age: Int): String = { 83 if (age > 18) { 84 "adult" 85 } else if (age > 12) "teenager" else "children" 86 } 87 88 // todo 无法读取 89 @Test 90 def gameTest(): Unit = { 91 //游戏厅门禁 92 val name = readLine("Welcome to Game House. Please tell me your name: ") 93 print("Thanks. Then please tell me your age: ") 94 val age = readInt() 95 if (age > 18) { 96 printf("Hi, %s, you are %d years old, so you are legel to come here!", name, age) 97 } else { 98 printf("Sorry, boy, %s, you are only %d years old. you are illegal to come here!", name, age) 99 } 100 } 101 102 @Test 103 def whileTest(): Unit = { 104 //循环 105 //Scala有while do循环,基本语义与Java相同。 106 var n = 10 107 while (n > 0) { 108 println(n) 109 n -= 1 110 } 111 } 112 113 @Test 114 def forTest(): Unit = { 115 //Scala没有for循环,只能使用while替代for循环,或者使用简易版的for语句 116 val n = 10; 117 118 for (i <- 1 to n) println(i) 119 120 //使用until,表式不达到上限(1-9) 121 for (i <- 1 until n) println(i) 122 123 //对字符串进行遍历,类似于java的增强for循环 124 for (c <- "Hello World") print(c) 125 } 126 127 @Test 128 def breakTest(): Unit = { 129 //scala没有提供类似于java的break语句。但是可以使用boolean类型变量、return或者Breaks的break函数来替代使用。 130 import scala.util.control.Breaks._ 131 breakable { 132 var n = 10 133 for (c <- "Hello World") { 134 if (n == 5) break; 135 print(c) 136 n -= 1 137 } 138 } 139 } 140 141 @Test 142 def doubleForTest(): Unit = { 143 //多重for循环:九九乘法表 144 for (i <- 1 to 9; j <- 1 to 9) { 145 if (j == 9) { 146 println(i * j) 147 } else { 148 print(i * j + " ") 149 } 150 } 151 } 152 153 @Test 154 def ifGuardTest(): Unit = { 155 //if守卫:取偶数 156 for (i <- 1 to 100 if i % 2 == 0) print(i + " ") 157 println() 158 159 //for推导式:构造集合 160 //for循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。 161 val vector = for (i <- 1 to 10) yield i 162 print(vector) 163 } 164 165 //函数 166 @Test 167 def funcTest(): Unit = { 168 sayHello1("zy", 30) 169 170 sayHello2("lx") 171 } 172 173 //在Scala中定义函数时,需要定义函数的 函数名、参数、函数体。 174 //Scala要求必须给出所有参数的 类型,但是不一定给出函数 返回值的类型 175 //只要函数体中不包含递归的语句,Scala就可以自己根据表达式推断出返回类型。 176 private def sayHello1(name: String, age: Int) = { 177 if (age > 18) { 178 printf("hi %s, you are a big boy\n", name); 179 age 180 } 181 else { 182 printf("hi %s, you are a little boy\n", name); 183 age 184 } 185 } 186 187 //单行的函数 Unit相当于void 188 def sayHello2(name: String): Unit = print("Hello, " + name) 189 190 @Test 191 def fabTest(): Unit = { 192 println(fab(10)) 193 } 194 195 //如果在函数体内递归调用函数自身,则必须手动给出函数的返回类型。 196 //斐波那契数列 197 def fab(n: Int): Int = { 198 if (n <= 1) 1 199 else fab(n - 1) + fab(n - 2) 200 } 201 202 @Test 203 def paramTest(): Unit = { 204 //在调用函数时,也可以 不按照函数定义的参数顺序 来传递参数,而是使用带名参数的方式来传递。 205 println(sayHello3(firstName = "胡", lastName = "宪", middleName = "宗")) 206 //还可以 混合使用未命名参数和带名参数,但是未命名参数必须排在带名参数前面。 207 println(sayHello3("胡", lastName = "宪", middleName = "宗")) 208 //传入名字,年龄默认 209 sayHello4("萌萌") 210 } 211 212 //在Scala中,有时我们调用某些函数时,不希望给出参数的具体值,而希望使用参数自身默认的值,此时就定义在定义函数时使用默认参数。 213 private def sayHello3(firstName: String, middleName: String = "William", lastName: String = "Croft") = firstName + " " + middleName + " " + lastName 214 215 def sayHello4(name: String, age: Int = 20) { 216 print("Hello " + name + ", your age is " + age) 217 } 218 219 @Test 220 def sumTest(): Unit = { 221 println(sum(1, 2, 3, 4, 5)) 222 //如果想要将一个已有的序列直接调用变长参数函数,是不对的。比如val s = sum(1 to 5)。 223 // 此时需要使用Scala特殊的语法将参数定义为序列,让Scala解释器能够识别。这种语法非常有用! 224 // 一定要好好注意,在spark的源码中大量地使用到了。 225 // _*将1 to 5转化为参数序列 226 val s = sum(1 to 5: _*) 227 println(s) 228 } 229 230 //在Scala中,有时我们需要将函数定义为参数个数可变的形式,则此时可以使用变长参数定义函数。 231 def sum(nums: Int*) = { 232 var res = 0 233 for (num <- nums) res += num 234 res 235 } 236 237 //使用递归函数实现累加 238 def sum2(nums: Int*): Int = { 239 if (nums.length == 0) 0 240 else nums.head + sum2(nums.tail: _*) 241 } 242 243 @Test 244 def lazyTest(): Unit = { 245 //在Scala中,提供了lazy值的特性,也就是说,如果将一个变量声明为lazy,则只有在第一次使用该变量时,变量对应的表达式才会发生计算。 246 //这种特性对于特别耗时的计算操作特别有用,比如打开文件进行IO,进行网络IO等。 247 //即使文件不存在,也不会报错,只有第一个使用变量时会报错,证明了表达式计算的lazy特性。 248 import scala.io.Source._ 249 lazy val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString 250 println(lines) 251 } 252 253 @Test 254 def exceptionTest(): Unit = { 255 //在Scala中,异常处理和捕获机制与Java是非常相似的。 256 import java.io.IOException 257 try { 258 throw new IOException("user defined exception") 259 } catch { 260 case e1: IllegalArgumentException => println("illegal argument") 261 case e2: IOException => println("io exception") 262 } 263 } 264 265 }
补充:Scala的数据类型
Scala 与 Java有着一些相同的数据类型,下表列出了 Scala 支持的数据类型:
数据类型 | 描述 |
---|---|
Byte | 8位有符号补码整数。数值区间为 -128 到 127 |
Short | 16位有符号补码整数。数值区间为 -32768 到 32767 |
Int | 32位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long | 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 |
Float | 32位IEEE754单精度浮点数 |
Double | 64位IEEE754单精度浮点数 |
Char | 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF |
String | 字符序列 |
Boolean | true或false |
Unit | 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。 |
Null | null 或空引用 |
Nothing | Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。 |
Any | Any是所有其他类的超类 |
AnyRef | AnyRef类是Scala里所有引用类(reference class)的基类 |