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)的基类