Scala入门教程---《chang哥教你一天搞定Scala》
《chang哥教你一天搞定Scala》
1 /** 2 * 《chang哥教你一天搞定Scala》 3 * scala是一门多范式编程语言,集成了面向对象编程和函数式编程等多种特性。 4 * scala运行在虚拟机上,并兼容现有的Java程序。 5 * Scala源代码被编译成java字节码,所以运行在JVM上,并可以调用现有的Java类库。 6 */ 7 8 /** 9 * 第一个Scala程序 10 * Scala和Java最大的区别是:Scala语句末尾的分号(;)是可选的! 11 * 编译运行: 12 * 先编译:scalac HelloScala.scala 将会生成两个文件:HelloScala$.class和HelloScala.class 13 * 在运行:scala HelloScala 14 * 输出结果:hello scala!!! 15 * 16 * object HelloScala{ 17 def main(args: Array[String]): Unit = { 18 println("hello scala!!!") 19 } 20 } 21 */ 22 23 /** 24 * Scala基本语法: 25 * 区分大小写 26 * 类名首字母大写(MyFirstScalaClass) 27 * 方法名称第一个字母小写(myMethodName()) 28 * 程序文件名应该与对象名称完全匹配 29 * def main(args:Array[String]):scala程序从main方法开始处理,程序的入口。 30 * 31 * Scala注释:分为多行/**/和单行// 32 * 33 * 换行符:Scala是面向行的语言,语句可以用分号(;)结束或换行符(println()) 34 * 35 * 定义包有两种方法: 36 * 1、package com.ahu 37 * class HelloScala 38 * 2、package com.ahu{ 39 * class HelloScala 40 * } 41 * 42 * 引用:import java.awt.Color 43 * 如果想要引入包中的几个成员,可以用selector(选取器): 44 * import java.awt.{Color,Font} 45 * // 重命名成员 46 * import java.util.{HashMap => JavaHashMap} 47 * // 隐藏成员 默认情况下,Scala 总会引入 java.lang._ 、 scala._ 和 Predef._,所以在使用时都是省去scala.的 48 * import java.util.{HashMap => _, _} //引入了util包所有成员,但HashMap被隐藏了 49 */ 50 51 /** 52 * Scala数据类型: 53 * Scala与Java有着相同的数据类型,下面列出一些Scala有的数据类型。 54 * Unit:表示无值,和其他语言的void一样。 55 * Null:null或空引用。 56 * Nothing:是Scala的类层级的最低端,是任何其他类型的子类型。 57 * Any:是所有其他类的超类。 58 * AnyRef:是Scala所有引用类的基类。 59 * 60 * 多行字符串的表示方法: 61 val foo ="""第一行 62 第二行 63 第三行""" 64 */ 65 66 /** 67 * Scala变量: 68 * 在Scala中,使用关键字“var”声明变量,使用关键字“val”声明常量。 69 * var myVar1 : String = "foo" 70 * var myVar2 : Int 71 * val myVal = "Hello,Scala!" 72 * Scala多个变量声明: 73 * val xmax, ymax = 100 // xmax,ymax都声明为100 74 */ 75 76 /** 77 * Scala访问修饰符: 78 * Scala访问修饰符和Java基本一样,分别有private、protected、public。 79 * 默认情况下,Scala对象的访问级别是public。 80 * 81 * 私有成员:用private关键字修饰的成员仅在包含了成员定义的类或对象内部可见。 82 * class Outer{ 83 * class Inner{ 84 * private def f(){println("f")} 85 * class InnerMost{ 86 * f() // 正确 87 * } 88 * (new Inner).f() // 错误 89 * } 90 * } 91 * 92 * 保护成员:Scala比Java中更严格。只允许保护成员在定义了该成员的类的子类中被访问。 93 * package p{ 94 * class Super{ 95 * protected def f() {println("f")} 96 * } 97 * class Sub extends Super{ 98 * f() 99 * } 100 * class Other{ 101 * (new Super).f() // 错误 102 * } 103 * } 104 * 105 * 公共成员:默认public,这样的成员在任何地方都可以被访问。 106 * class Outer{ 107 * class Inner{ 108 * def f(){println("f")} 109 * class InnerMost{ 110 * f() // 正确 111 * } 112 * } 113 * (new Inner).f() // 正确 114 * } 115 * 116 * 作用域保护:Scala中,访问修饰符可以通过使用限定词强调。 117 * private[x] 或者 protected[x] 118 * private[x]:这个成员除了对[...]中的类或[...]中的包中的类及他们的伴生对象可见外,对其他的类都是private。 119 */ 120 121 /** 122 * Scala运算符:和Java一样,这里就不再浪费时间一一介绍了。 123 * 算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符。 124 */ 125 126 /** 127 * Scala if...else语句:和Java一样,简单列举一下四种情况。 128 * if(...){ 129 * 130 * } 131 * 132 * if(...){ 133 * 134 * }else{ 135 * 136 * } 137 * 138 * if(...){ 139 * 140 * }else if(...){ 141 * 142 * }else{ 143 * 144 * } 145 * 146 * if(...){ 147 * if(...){ 148 * 149 * } 150 * } 151 */ 152 153 /** 154 * Scala循环:和Java一样,这里不赘述,只介绍三种循环类型。 155 * while循环、do...while循环、for循环 156 */ 157 158 /** 159 * Scala函数:用一个例子来说明函数的定义和函数调用。 160 * object Test{ 161 * def main(args: Array[String]){ 162 * println(addInt(1,3)); // 函数调用 163 * } 164 * def addInt(a:Int, b:Int) : Int = { // 函数定义 165 * var sum:Int = 0 166 * sum = a + b 167 * return sum 168 * } 169 * } 170 */ 171 172 /** 173 * Scala闭包: 174 * 闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。 175 * 例子: 176 * object Test{ 177 * def main(args: Array[String]){ 178 * println("muliplier(1) value = " + muliplier(1)) 179 * println("muliplier(2) value = " + muliplier(2)) 180 * } 181 * var factor = 3 // 定义在函数外的自由变量 182 * val muliplier = (i:Int) => i * factor // muliplier函数变量就是一个闭包 183 * } 184 * 输出结果: 185 * muliplier(1) value = 3 186 * muliplier(2) value = 6 187 */ 188 189 /** 190 * Scala字符串: 191 * 192 * Scala中可以创建两中字符串:一种是不可修改的,一种是可以修改的。 193 * // 创建不可修改的字符串 194 * val greeting:String = "Hello World!"; 195 * // 创建可以修改的字符串 196 * object Test{ 197 * def main(args: Array[String]){ 198 * val buf = new StringBuilder; 199 * buf += 'a' // 添加一个字符 200 * buf ++= "bcdef" // 添加一个字符串 201 * println(buf.toString); // 输出:abcdef 202 * } 203 * } 204 * 205 * 字符串长度:xxx.length() 206 * 207 * 字符串连接:可以用concat()方法或者用加号 208 * object Test { 209 def main(args: Array[String]) { 210 var str1 = "字符串1:"; 211 var str2 = "字符串2"; 212 var str3 = "字符串3:"; 213 var str4 = "字符串4"; 214 println( str1 + str2 ); // 字符串1:字符串2 215 println( str3.concat(str4) ); // 字符串3:字符串4 216 } 217 } 218 * 219 * 创建格式化字符串: 220 * String类中可以使用printf()方法来格式化字符串并输出。 221 * object Test{ 222 * def main(args:Array[String]){ 223 * var floatVar = 12.456 224 * var intVar = 2000 225 * var stringVar = "字符串变量" 226 * var fs = printf("浮点型变量为 " + 227 * "%f,整形变量为 %d, 字符串为 " + 228 * "%s", floatVar, intVar, stringVar) 229 * println(fs) // 浮点型变量为 12.456000, 整型变量为 2000, 字符串为 字符串变量 230 * } 231 * } 232 */ 233 234 /** 235 * Scala数组: 236 * 1、声明数组 237 * var z:Array[String] = new Array[String](3) 或者 var z = new Array[String]() 238 * z(0) = "value1"; z(1) = "value2"; z(2) = "value3" 239 * 240 * var z = Array("value1", "value2", "value3") 241 * 242 * 2、处理数组 243 * object Test{ 244 * def main(args: Array[String]){ 245 * var myList = Array(1.1, 2.2, 3.3, 4.4) 246 * 247 * // 输出所有数组元素 248 * for(x <- myList){ 249 * println(x) 250 * } 251 * 252 * // 计算数组所有元素的总和 253 * var total = 0.0 254 * for(i <- 0 to (myList.length - 1)){ 255 * total += myList(i) 256 * } 257 * println("总和:" + total) 258 * 259 * // 查找数组中的最大元素 260 * var max = myList(0) 261 * for(i <- 1 to (myList.length - 1)){ 262 * if(myList(i) > max) 263 * max = myList(i) 264 * } 265 * println("最大值:" + max) 266 * } 267 * } 268 * 269 * 3、多维数组 270 * import Array._ 271 * object Test{ 272 * def main(args: Array[String]){ 273 * // 定义数组 274 * var myMatrix = ofDim[Int](3,3) 275 * // 创建矩阵 276 * for(i <- 0 to 2){ 277 * for(j <- 0 to 2){ 278 * myMatrix(i)(j) = j; 279 * } 280 * } 281 * // 打印矩阵 282 * for(i <- 0 to 2){ 283 * for(j <- 0 to 2){ 284 * print(" " + myMatrix(i)(j)); 285 * } 286 * println(); 287 * } 288 * } 289 * } 290 * 291 * 4、合并数组 292 * import Array._ 293 * object Test{ 294 * def main(args: Array[String]){ 295 * var myList1 = Array(1.1, 2.2, 3.3, 4.4) 296 * var myList2 = Array(5.5, 6.6, 7.7, 8.8) 297 * // 使用concat()合并 298 * var myList3 = concat(myList1, myList2) 299 * // 输出所有数组元素 300 * for(x <- myList3){ 301 * println(x) 302 * } 303 * } 304 * } 305 * 306 * 5、创建区间数组:使用range(x,y,z)创建区间数组,数值范围大于等于x,小于y。z表示步长,默认为1。 307 * object Test{ 308 * def main(args: Array[String]){ 309 * var myList1 = range(10, 20, 2) 310 * var myList2 = range(10, 20) 311 * for(x <- myList1){ 312 * print(" " + x) //输出:10 12 14 16 18 313 * } 314 * println() 315 * for(x <- myList2){ 316 * print(" " + x) // 输出:10 11 12 13 14 15 16 17 18 19 317 * } 318 * } 319 * } 320 */ 321 322 /** 323 * Scala集合:分为可变集合和不可变集合。 324 * 可变集合:可以在适当的地方被更新或扩展,也就是可以修改、添加、移除一个集合的元素。 325 * 不可变集合:永远不会改变。但可以模拟添加、移除、更新操作,但是这些操作将在每一种情况下都返回一个新的集合, 326 * 同时使原来的集合不发生改变。 327 * // 定义整形List 328 * val x = List(1,2,3,4) 329 * // 定义Set 330 * var x = Set(1,3,5,7) 331 * // 定义Map 332 * val x = Map("one" -> 1, "two" -> 2, "three" -> 3) 333 * // 创建两个不同类型的元组 334 * val x = (10, "Runoob") 335 * // 定义Option 336 * val x:Option[Int] = Some(5) 337 */ 338 339 /** 340 * Scala迭代器: 341 * 迭代器不是一个集合,而是一个用于访问集合的方法。 342 * 343 */ 344 /*object Test{ 345 def main(args: Array[String]): Unit = { 346 val it = Iterator("one", "two", "three", "four") 347 while(it.hasNext){ // 检测集合中是否还有元素 348 println(it.next()) // 返回迭代器的下一个元素,并更新迭代器的状态 349 } 350 351 val ita = Iterator(1, 2, 3, 4, 5) 352 val itb = Iterator(11, 22, 33, 44, 55) 353 //println(ita.max) // 查找最大元素 354 //println(itb.min) // 查找最小元素 355 356 println(ita.size) // 获取迭代器的长度 357 println(itb.length) // 获取迭代器的长度 358 } 359 }*/ 360 361 /** 362 * Scala类和对象: 363 * 类是对象的抽象,对象是类的具体实例。 364 * 类是抽象的,不占用内存;对象是类的具体实例,占用存储空间。 365 * 366 */ 367 /*import java.io._ 368 class Point(xc: Int, yc: Int){ 369 var x: Int = xc 370 var y: Int = yc 371 def move(dx: Int, dy: Int): Unit ={ 372 x = x + dx 373 y = y + dy 374 println("x点的坐标是:" + x) 375 println("y点的坐标是:" + y) 376 } 377 } 378 object Test{ 379 def main(args: Array[String]): Unit = { 380 val pt = new Point(10, 20) 381 // 移到一个新的位置 382 pt.move(10, 10) 383 } 384 }*/ 385 /** 386 * Scala继承:跟Java差不多。 387 * 1、重写一个非抽象方法必须使用override修饰符 388 * 2、只有主构造函数才可以往基类的构造函数里写参数 389 * 3、在子类中重写超类的抽象方法时,不需要使用override 390 */ 391 /*class Point(val xc: Int, val yc: Int){ 392 var x: Int = xc 393 var y: Int = yc 394 def move(dx: Int, dy: Int): Unit ={ 395 x = x + dx 396 y = y + dy 397 println("x点的坐标是:" + x) 398 println("y点的坐标是:" + y) 399 } 400 //------------------------------------- 401 var name = "" 402 override def toString = getClass.getName + "[name=" + name + "]" 403 } 404 class Location(override val xc: Int, override val yc: Int, 405 val zc: Int) extends Point(xc, yc){ // 继承 重写了父类的字段 406 var z: Int = zc 407 def move(dx: Int, dy: Int, dz: Int){ 408 x = x + dx 409 y = y + dy 410 z = z + dz 411 println("x点的坐标是:" + x) 412 println("y点的坐标是:" + y) 413 println("z点的坐标是:" + z) 414 } 415 //--------------------------------------- 416 var salary = 0.0 417 override def toString = super.toString + "[salary=" + salary + "]" 418 } 419 object Test{ 420 def main(args: Array[String]): Unit = { 421 val loc = new Location(10, 20, 30) 422 loc.move(10, 10 ,5) 423 //------------------------------------ 424 loc.name = "lc" 425 loc.salary = 35000.0 426 println(loc) 427 } 428 }*/ 429 430 /** 431 * Scala单例对象: 432 * Scala中没有static,要使用object关键字实现单例模式。 433 * Scala中使用单例模式时,除了定义类,还要定义一个同名的object对象,它和类的区别是,object对象不能带参数。 434 * 当单例对象与某个类共享一个名称时,他被称作这个类的伴生对象。 435 * 必须在同一个源文件里定义类和它的伴生对象。 436 * 类和它的伴生对象可以互相访问其私有成员。 437 */ 438 /*// 私有构造方法 439 class Marker private(val color:String) { 440 println("创建" + this) 441 override def toString(): String = "颜色标记:"+ color //4:颜色标记:red 442 } 443 444 // 伴生对象,与类共享名字,可以访问类的私有属性和方法 445 object Marker{ 446 private val markers: Map[String, Marker] = Map( 447 "red" -> new Marker("red"), //1:创建颜色标记:red 448 "blue" -> new Marker("blue"), //2:创建颜色标记:blue 449 "green" -> new Marker("green") //3:创建颜色标记:green 450 ) 451 452 def apply(color:String) = { 453 if(markers.contains(color)) markers(color) else null 454 } 455 456 def getMarker(color:String) = { 457 if(markers.contains(color)) markers(color) else null //5:颜色标记:blue 458 } 459 460 def main(args: Array[String]) { 461 println(Marker("red")) 462 // 单例函数调用,省略了.(点)符号 463 println(Marker getMarker "blue") 464 } 465 }*/ 466 467 /** 468 * Scala Trait(特征): 469 * 相当于Java的接口,但比接口功能强大,它还可以定义属性和方法的实现。 470 * 一般情况下Scala的类只能单继承,但特征可以实现多重继承。 471 */ 472 /*// 定义特征 473 trait Equal{ 474 def isEqual(x: Any): Boolean // 未实现的方法 475 def isNotEqual(x: Any): Boolean = !isEqual(x) // 实现了的方法 476 } 477 478 class Point(xc: Int, yc: Int) extends Equal{ 479 var x: Int = xc 480 var y: Int = yc 481 482 override def isEqual(obj: Any): Boolean = 483 obj.isInstanceOf[Point] && 484 obj.asInstanceOf[Point].x == x 485 } 486 487 object Test{ 488 def main(args: Array[String]): Unit = { 489 val p1 = new Point(2, 3) 490 val p2 = new Point(2, 4) 491 val p3 = new Point(3, 3) 492 println(p1.isNotEqual(p2)) 493 println(p1.isNotEqual(p3)) 494 println(p1.isNotEqual(2)) 495 } 496 }*/ 497 498 /** 499 * 特征构造顺序: 500 * 构造器的执行顺序: 501 * 1、调用超类的构造器 502 * 2、特征构造器在超类构造器之后、类构造器之前执行 503 * 3、特征由左到右被构造 504 * 4、每个特征当中,父特征先被构造 505 * 5、如果多个特征共有一个父特征,父特征不会被重复构造 506 * 6、所有特征被构造完毕,子类被构造 507 */ 508 509 /** 510 * Scala模式匹配: 511 * 选择器 match {备选项} 512 */ 513 /*object Test{ 514 def main(args: Array[String]): Unit = { 515 println(matchTest("two")) 516 println(matchTest("test")) 517 println(matchTest(1)) 518 println(matchTest(6)) 519 } 520 def matchTest(x: Any): Any = x match { 521 case 1 => "one" 522 case "two" => 2 523 case y: Int => "scala.Int" // 对应类型匹配 524 case _ => "many" // 默认全匹配选项 525 } 526 }*/ 527 /** 528 * 使用样例类: 529 * 使用case关键字的类定义就是样例类,样例类是种特殊的类,经过优化以用于模式匹配。 530 */ 531 /*object Test{ 532 def main(args: Array[String]): Unit = { 533 val alice = new Person("Alice", 25) 534 val bob = new Person("Bob", 32) 535 val charlie = new Person("Charlie", 27) 536 for(person <- List(alice, bob, charlie)){ 537 person match{ 538 case Person("Alice", 25) => println("Hi Alice!") 539 case Person("Bob", 32) => println("Hi Bob!") 540 case Person(name, age) => println("Age: " + age + " year,name: " + name +"?") 541 } 542 } 543 } 544 // 样例类 545 case class Person(name: String, age: Int) 546 }*/ 547 548 /** 549 * Scala正则表达式: 550 * 和Java差不多,在用的时候查一下就行了。 551 */ 552 553 /** 554 * Scala异常处理: 555 * 和Java类似。在Scala中借用了模式匹配的方法来在catch语句块中来进行异常匹配。 556 */ 557 /*import java.io.{FileNotFoundException, FileReader, IOException} 558 object Test{ 559 def main(args: Array[String]): Unit = { 560 try { 561 val f = new FileReader("input.txt") 562 }catch { 563 case ex: FileNotFoundException => { 564 println("Missing file exception") 565 } 566 case ex: IOException => { 567 println("IO Exception") 568 } 569 }finally { 570 println("Exiting finally...") 571 } 572 } 573 }*/ 574 575 /** 576 * Scala提取器(Extractor): 577 * apply方法:无需new操作就可创建对象。 578 * unapply方法:是apply方法的反向操作,接受一个对象,然后从对象中提取值,提取的值通常是用来构造对象的值。 579 */ 580 /*object Test { 581 def main(args: Array[String]) { 582 583 println ("Apply 方法 : " + apply("Zara", "gmail.com")); // 也可直接Test("Zara", "gmail.com")来创建Zara@gmail.com 584 println ("Unapply 方法 : " + unapply("Zara@gmail.com")); 585 println ("Unapply 方法 : " + unapply("Zara Ali")); 586 587 } 588 // 注入方法 (可选) 589 def apply(user: String, domain: String) = { 590 user +"@"+ domain 591 } 592 593 // 提取方法(必选) 594 def unapply(str: String): Option[(String, String)] = { 595 val parts = str split "@" 596 if (parts.length == 2){ 597 Some(parts(0), parts(1)) 598 }else{ 599 None 600 } 601 } 602 }*/ 603 /** 604 * 提取器使用模式匹配: 605 * 在我们实例化一个类的时,可以带上0个或者多个的参数,编译器在实例化的时会调用 apply 方法。 606 */ 607 /*object Test { 608 def main(args: Array[String]) { 609 610 val x = Test(5) 611 println(x) 612 613 x match 614 { 615 case Test(num) => println(x + " 是 " + num + " 的两倍!") //2:10是5的两倍! 616 //unapply 被调用 617 case _ => println("无法计算") 618 } 619 620 } 621 def apply(x: Int) = x*2 //1:10 622 def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None 623 }*/ 624 625 /** 626 * Scala文件I/O: 627 * 628 */ 629 /*// 文件写操作 630 import java.io._ 631 object Test { 632 def main(args: Array[String]) { 633 val writer = new PrintWriter(new File("test.txt" )) 634 635 writer.write("Scala语言") 636 writer.close() 637 } 638 }*/ 639 // 从屏幕上读取用户输入 640 /*object Test { 641 def main(args: Array[String]) { 642 print("请输入菜鸟教程官网 : " ) 643 val line = Console.readLine // 在控制台手动输入 644 645 println("谢谢,你输入的是: " + line) 646 } 647 }*/ 648 // 从文件上读取内容 649 /*import scala.io.Source 650 object Test { 651 def main(args: Array[String]) { 652 println("文件内容为:" ) 653 654 Source.fromFile("test.txt" ).foreach{ 655 print 656 } 657 } 658 }*/
一起学习,一起进步