简单了解Scala
概述
- spark作为新一代的内存级大数据计算框架,是大数据的重要内容。而spark就是由scala进行编写的,为了更好的学习spark,scala语言编程是不可或缺的一项技能。
- Scala可以与Java互操作。它用scalac这个编译器把源文件编译成Java的class文件(即在JVM上运行的字节码)。你可以从Scala中调用所有的Java类库,也同样可以从Java应用程序中调用Scala的代码。
scala和java的关系
一般而言,我们会认为scala语言是基于java语言的。
正如我们所知道的,java语言中,代码会被javac编译器编译成class字节码文件,然后再运行于JVM之上,通过不同的JVM适配不同的运行环境,从而做到跨平台运行。
而scala语言的代码,则是类似的,通过scalac编译器被编译为与java同等的class字节码文件,然后再运行于JVM之上。
基于scala的这个特征,scala中兼并了一部分的java语法,并包含了java的部分类库,同时在这些类库之外还对java的一些类库进行了包装。与此同时,scala还有一些自己特有的类库。
scala语言的特点
scala是一门以java虚拟机作为运行环境并将面向对象和函数式编程的特性结合在一起的静态类型编程语言:
- scala是一门多范式的编程语言,scala支持面向对象和函数式编程
- scala源代码会编译为class字节码,scala可以调用现有的java类库,并实现两种语言的无缝对接
- scala的语法十分简洁,特点鲜明
- scala源于java,在scala设计之初,其创始人马丁·奥德斯基将函数式编程语言的特点融合到java之中,因此,对于已经学习过java的朋友,只要区分两种语言间的相同点和不同点,就可以很快捷的掌握scala
scala的环境安装与idea适配scala语言的配置
HelloWorld案例
创建idea项目
首先创建一个普通的maven项目,在默认的情况下,maven不支持scala的开发的,因此需要引入scala框架。
引入方法为:右键项目点击-> add framework support… ,找到并选择scala
如图:
然后创建项目中scala的源文件目录:
右键main目录->创建一个diretory -> 写个名字(比如scala)->右键scala目录->mark directory ->选择source root即可。
如图:
创建包,包名随意。
然后就可以新建一个scala类,开始编码了。
PS:如果这里见不到Scala Class的选项,那可能就是你还没有引入scala框架,或者没有配置好idea对scala的支持。
/**
* 关于完全面向对象:scala语言完全面向对象,
* 因此移除了一些在java中非面向对象的元素。
* 如:static关键字或void类型
* 1、在scala中,没有static关键字,通过object实现类似静态方法的功能
* 通过object定义类与通过class定义类的方式相同,但作用不同。
* class关键字和java中的class关键字相同,用于定义一个类
* object的作用则是声明一个单例对象,object后的类名可以理解为该单例对象的变量名
* 2、对于那些没有返回值的函数,scala将其返回值定义为Unit类
*/
object HelloWorld {
/*
定义变量的方法:
val/var 变量名:变量类型 = 变量值
*/
var str: String = "hello world"
/*
定义方法:
def 函数名(参数名:参数类型……):返回值类型 = {方法体}
*/
def hello(): Unit = {
println(str)
}
/*
程序的入口,main方法,只能在object修饰的类中生效
*/
def main(args: Array[String]): Unit = {
hello()
}
}
运行main方法后输出:hello world,成功。
scala程序反编译
通过idea项目目录中的target目录,我们可以很轻松的找到自己的代码编译后的字节码所在,然后通过反编译软件进行一下反编译,就可以简单了解scala程序运行的过程。
如图:
我们可以看到,object修饰的类被编译成了两个文件,两个文件反编译为Java后,可以看到其内容中:
package cn.test;
import scala.Predef.;
public final class HelloWorld$
{
public static final MODULE$;
private String str;
static
{
new ();
}
public String str()
{
return this.str; }
public void str_$eq(String x$1) { this.str = x$1; }
public void hello()
{
Predef..MODULE$.println(str());
}
public void main(String[] args)
{
hello();
}
private HelloWorld$() { MODULE$ = this;
this.str = "hello world";
}
}
package cn.test;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes="\006\001Q:Q!\001\002\t\002\035\t!\002S3mY><vN\0357e\025\t\031A!\001\003uKN$(\"A\003\002\005\rt7\001\001\t\003\021%i\021A\001\004\006\025\tA\ta\003\002\013\021\026dGn\\,pe2$7CA\005\r!\ti\001#D\001\017\025\005y\021!B:dC2\f\027BA\t\017\005\031\te.\037*fM\")1#\003C\001)\0051A(\0338jiz\"\022a\002\005\b-%\001\r\021\"\001\030\003\r\031HO]\013\0021A\021\021\004\b\b\003\033iI!a\007\b\002\rA\023X\rZ3g\023\tibD\001\004TiJLgn\032\006\00379Aq\001I\005A\002\023\005\021%A\004tiJ|F%Z9\025\005\t*\003CA\007$\023\t!cB\001\003V]&$\bb\002\024 \003\003\005\r\001G\001\004q\022\n\004B\002\025\nA\003&\001$\001\003tiJ\004\003\"\002\026\n\t\003Y\023!\0025fY2|G#\001\022\t\0135JA\021\001\030\002\t5\f\027N\034\013\003E=BQ\001\r\027A\002E\nA!\031:hgB\031QB\r\r\n\005Mr!!B!se\006L\b")
public final class HelloWorld
{
public static void main(String[] paramArrayOfString)
{
HelloWorld..MODULE$.main(paramArrayOfString);
}
public static void hello()
{
HelloWorld..MODULE$.hello();
}
public static void str_$eq(String paramString)
{
HelloWorld..MODULE$.str_$eq(paramString);
}
public static String str()
{
return HelloWorld..MODULE$.str();
}
}
对这两个类进行了简单观察,然后通过查阅资料可知:
- 首先,对于object修饰的类,在编译后会生成两个类,其类名分别为:当前类、当前类$
- 使用当前类$的目的在于模拟静态语法,可以通过类名直接访问方法
- scala将当前类$这个对象称为伴生对象,伴随着类所产生的对象,这个对象中的方法可以直接使用
scala的一些注意事项
- scala源文件以.scala结尾
- scala程序的执行入口为object中的main方法
- scala语言严格区分大小写
- scala方法由一条条语句构成,每个语句后不需要加分号(因为scala语言会在每行末尾自动加分号)
- 同行如果有多条语句,通过分号分隔