第一章 - 基本概述
Read Me
- ? Code : 本章节代码实现
- ? CSDN : wangt的博客
- ☁️ Github : https://github.com/lovewangtzq
- ❤️ 微信公众号 : 大数据初学者
- ? b站: 我学不会Spark
why is Scala语言 ❓
- Spark—新一代内存级大数据计算框架,是大数据的重要内容。
- Spark就是使用Scala编写的。因此为了更好的学习Spark, 需要掌握Scala这门语言。
- Scala 是 Scalable Language 的简写,是一门多范式(范式/编程方式[面向对象/函数式编程])的编程语言
- 联邦理工学院洛桑(EPFL)的 ?Martin Odersky于2001年开始设计Scala
Scala 环境搭建 ⭐️
Scala程序的执行流程 ⭐️
-
使用一段测试代码 然后将生成的.class文件进行反编译 来理解Scala的基本原理 以及执行流程
-
测试代码
package base /** * 编写一段Scala 程序 反编译后查看Scala的程序的执行流程 * @author 王天赐 * @create 2019-07-12 10:10 */ object SimulationScalaExecutionFlow { def main(args: Array[String]): Unit = { val str : String = "Hello" println(str) } } class Student{ var name : String = "" var age : Int = -1 def setName(newValue : String) : Unit ={ this.name = newValue } }
-
可以看到上面的代码总共有两个部分 编译过后会生成 SimulationScalaExecutionFlow.class SimulationScalaExecutionFlow$.class和 Student.class 文件 下面的是对这两个文件进行反编译后得到的内容
1️⃣SimulationScalaExecutionFlow .calss
package base; import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\6\1\21:Q!\1\2\t\2\21\tAdU5nk2\fG/[8o'\14\fG.Y#yK\14,H/[8o\r2|wOC\1\4\3\17\17\23m]3\4\1A\17aaB\7\2\5\25)\1B\1E\1\19\ta2+[7vY\6$\24n\288TG\6d\23-\18=fGV$\24n\288GY><8CA\4\11!\tYa\"D\1\r\21\5i\17!B:dC2\f\23BA\b\r\5\25\te.\31*fM\")\17c\2C\1%\51A(\278jiz\"\18!\2\5\6)\29!\t!F\1\5[\6Lg\14\6\2\233A\171bF\5\311\17A!\228ji\")!d\5a\17\5!\17M]4t!\rYADH\5\3;1\17Q!\17:sCf\4\"a\b\18\15\5-\1\19BA\17\r\3\25\1&/\263fM&\171\5\n\2\7'R\20\24N\\4\11\5\5b\1") public final class SimulationScalaExecutionFlow { public static void main(String[] paramArrayOfString) { .MODULE$.main(paramArrayOfString); } }
2️⃣Student.class
package base; import scala.reflect.ScalaSignature; @ScalaSignature(bytes="\6\1Y2A!\1\2\1\11\t91\11^;eK:$(\"A\2\2\t\t\f7/Z\2\1'\t\1a\1\5\2\b\215\t\1BC\1\n\3\21\258-\257b\19\tY\1B\1\4B]f\20VM\26\5\6\27\1!\tAD\1\7y%t\23\14\30 \21\3=\1\"\1\5\1\14\3\tAqA\5\1A\2\19\51#\1\3oC6,W#\1\11\17\5UAbBA\4\23\19\t9\2\"\1\4Qe\22$WMZ\5\33i\17aa\21;sS:<'BA\f\t\17\29a\2\11A\5\2u\t\1B\\1nK~#S-\29\11\3=\5\2\"aB\16\n\5\1B!\1B+oSRDqAI\14\2\2\3\7A#A\2yIEBa\1\n\1!B\19!\18!\28b[\22\4\3b\2\20\1\1\4%\taJ\1\4C\30,W#\1\21\17\5\29I\19B\1\22\t\5\rIe\14\30\5\bY\1\1\r\17\"\1.\3\29\tw-Z0%KF$\"A\b\24\t\15\tZ\19\17!a\1Q!1\1\7\1Q!\n!\nA!Y4fA!)!\7\1C\1g\591/\26;OC6,GC\1\165\17\21)\20\71\1\21\3!qWm\30,bYV,\7") public class Student { private String name = ""; private int age = -1; public String name() { return this.name; } public void name_$eq(String x$1) { this.name = x$1; } public int age() { return this.age; } public void age_$eq(int x$1) { this.age = x$1; } public void setName(String newValue) { name_$eq(newValue); } }
3️⃣ SimulationScalaExecutionFlow$.class
package base; import scala.Predef.; public final class { public static final MODULE$; static { new (); } public void main() { String str = "Hello"; Predef..MODULE$.println(str); } private () { MODULE$ = this; } }
-
如上是我们对两个 .class文件进行反编译后得到的文件 首先我们分析 SimulationScalaExecutionFlow.class文件
object SimulationScalaExecutionFlow { def main(args: Array[String]): Unit = { val str : String = "Hello" println(str) } } // 上面是 scala 代码 下面是反编译后生成的代码 public final class SimulationScalaExecutionFlow { public static void main(String[] paramArrayOfString) { .MODULE$.main(paramArrayOfString); } } package base; import scala.Predef.; public final class SimulationScalaExecutionFlow$ { public static final SimulationScalaExecutionFlow$ MODULE$; static { new SimulationScalaExecutionFlow$(); } public void main() { String str = "Hello"; Predef..MODULE$.println(str); } private SimulationScalaExecutionFlow$() { MODULE$ = this; } }
⭐️分析 :
-
object 会在底层生成两个类 :
SimulationScalaExecutionFlow 和 SimulationScalaExecutionFlow$
-
SimulationScalaExecutionFlow 有一个main函数调用 .MODULE$ 中的main方法
-
SimulationScalaExecutionFlow$.MODULE$ 是静态的 可以直接调用.MODULE$的main
-
可以理解成我们写的scala代码放在了 SimulationScalaExecutionFlow$ 类中 ,在底层scala编译器做了一个封装
?总结 :
- Object 对象是一个单例的并且是不可变的对象,也就是说你在不同的类中使用的都是同一个对象
- Object 对象可以理解成是一个静态类,并且有些不同的是 它里面所有的方法或者变量都是静态的
-
-
其次我们分析 Student.class
class Student{ SimulationScalaExecutionFlow.main(Array("hello")) var name : String = "" var age : Int = -1 def setName(newValue : String) : Unit ={ this.name = newValue } } // 上面是 java代码 , 下面是scala代码 public class Student { private String name = ""; private int age = -1; public String name() { return this.name; } public void name_$eq(String x$1) { this.name = x$1; } public int age() { return this.age; } public void age_$eq(int x$1) { this.age = x$1; } public void setName(String newValue) { name_$eq(newValue); } }
⭐️分析 :
- 可以看到 scala 的类其实和java差不多,有区别的是 scala中定义的变量访问域都是私有化的,并且会自动提供get/set 方法并且它内部在使用时也是调用的 get/set方法
Scala程序开发注意事项(❤️)
- Scala源文件以 “.scala" 为扩展名
- Scala程序的执行入口是main()函数。
- Scala语言严格区分大小写。
- Scala方法由一条条语句构成,每个语句后不需要分号(Scala语言会在每行后自动加分号),这也体现出Scala的简洁性。(加上分号不会报错 , 但是最好别加,会被人鄙视)
- 如果在同一行有多条语句,除了最后一条语句不需要分号,其它语句需要分号
Scala的三种输出方式 ⭕️
- 一般我经常用的是 第一种 不过这个看个人喜好
/**
* scala输出的三种方式
* @author 王天赐
* @create 2019-07-12 11:28
*/
object ScalaPrintMethod {
def main(args: Array[String]): Unit = {
val str : String = "hello,scala"
val num : Double = 1.2
// 1.第一种类似于java的输出方式
println("str = " + str + ", num =" + num)
// 2.第二种类似于 c 语言的输出方式 (tip : c语言中浮点数默认是输出6位)
printf("str = %s , num = %f\n" , str , num)
// 3.第三种类似于 php 的输出方式
println(s"str = ${str} , num = ${num}")
}
}
// 输出结果
str = hello,scala, num =1.2
str = hello,scala , num = 1.200000
str = hello,scala , num = 1.2
Scala 中的注释 ?
-
单行注释
// 1.第一种类似于java的输出方式 println("str = " + str + ", num =" + num)
-
多行注释
/* 多行注释 */
-
文档注释
/** * 计算两个数的和 * @param a 第一个数 * @param b 第二个数 * @return 两个数的和 */ def sum(a : Int , b : Int) = a + b
文档注释的内容在生成文档时会保存在文档中,一般在类和方法前面增加文档注释