专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Scala之:从零开始的Scala生活

Scala简介

它的老大哥Java曾几何时横扫市场,Scala语言相比之下显得名不见经传。直到互联网也开始经历一场“百年未有之大变局”:go, kotlin, python等语言异军突起…….

104_1.png(图片来自网络)

大数据时代到来,让Scala迎来了春天。Spark框架现在已经成为目前大数据事实上的计算标准框架,而Spark的原生开发语言正是默默无闻的Scala。Spark的开发人员为什么要选择Scala作为开发语言呢?

Scala的名字和设计理念都来源于:Scalable(可扩展的)。它融入了声明式编程,函数式编程的思想,同时将原本的OOP思想发扬光大,大大提高了大数据计算的开发效率。

还有一个背景:Java在大数据开发中仍旧占领着话语权:比如要使用Hadoop生态圈下的各种技术(Kafka,ZooKeeper,其它跟Apache基金会扯上关系的项目,etc),有个最基本的要求:配置JDK。

但Java的缺陷也比较明显:它太庞大了(这个情况在2013年Java 8版本之后有了改观,目前为止JDK已经更新到14版本,已经有了相当多的新内容)。完成一个功能,Python可能只需要1句话,而Java则需要手写大量的逻辑……显然拿Java去编写一个计算框架需要非常非常冗长的代码。

Spark的开发者想要寻找一个这样的开发工具:由它开发的框架既能够兼容其它运行在JVM的大数据框架,又想让代码变得简洁高效。如此看来,最适合的语言非Scala莫属。

Scala也站在“巨人的肩膀”上解决问题:它的老大哥Java留下的车轮,它都可以拿来用。同样的,它也为Java提供了很多新的思路:比如Java 8的诞生。

为什么Spark选择了Scala?

Scala与Java的关系

104_2.png

1、 除了Scala自身的独特语法之外,还能够支持部分Java的语法。
2、 SDK是依赖于JDK之上运行的。
3、 Scala推崇函数式编程:它引入了偏函数,函数柯里化,高阶函数的概念,函数是Scala的一等公民
4、 从底层来看,所有的Scala代码实际上是Java类/接口的包装。
5、 Scala 和 Java 8 编译器都出自大神马丁·奥德斯基,因此在Java 8中多多少少能看到一点Scala的“影子”。
6、 Scala将OOP思想发挥了极致!它的“基本”数据类型也属于对象,并像Java的包装类一样提供了很多便捷方法。
7、 Java有两个命令:javacjava,分别用于编译和运行。Scala也有对应的两个命令:scalacscala

Scala语言的特点

不同于Python,javaScript等解释型语言,Scala同Java一样,是一门静态类型编程语言。先编译,然后在JVM上运行。

Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程,且函数的地位被大大提高了

Scala参考了Java的设计思想,同时又将函数式编程的思想融入到了Java中。

Scala环境安装

Scala的运行依赖于JDK。并且SDK的版本号需要与其相对应,请注意。

windows平台

1、 Windows10下安装scala可以选择.msi一键安装,安装程序会自动按照安装目录配置SCALA_HOMEPATH。但是注意一点!!!安装路径绝对不能带空格和中文,一般程序默认的安装路径是C:/program file,该路径带空格,因此容易出现错误。
2、 也可以选择下载zip包然后直接解压到对应的目录当中,但是需要人工配置SCALA_HOME和PATH,配置方式与JDK无异。

Linux平台

1、 LInux(CENTOS)系统下安装scala,则需要从官网上下载tgz格式的压缩包,发送到虚拟机中并解压,配置。

#--------profile文件新增以下配置-----------#
export SCALA_HOME={安装目录}
export PATH= $PATH:$SCALA_HOME/bin
#------------重启配置--------------——-----#
source /etc/profile

Scala开发工具

实际上,一个大数据项目常常是Java与Scala进行混合开发,因此Scala的开发工具仍然选择Jet Brains公司旗下的IntelliJ IEDA。

但是IDEA没有默认支持Scala开发,需要导入Scala插件Plugin。在IDEA的settings页面下载对应版本。

104_3.png

Jet Brains的插件地址如下,可以下载到本地后选择:install from the disk.

Jet Brains插件官网

开发Scala代码选择在Windows环境中进行。

从“Hello Scala”开始创建第一个scala程序

感受一下Scala主函数和Java主函数的区别:

object HelloScala {
 //定义 主函数(参数:数组[里面是String类型]):unit = {结构体}
 def main(args:Array[String]): unit ={

 }
}
//Java type:
//public class HelloJava {
//  public static void main(String[] args) {
//   System.out.println("Hello Java!");
//  }
//}

Scala中的object表示它是一个伴生对象(有关于它的具体定义在后续的篇章中介绍),后面的HelloScala即这个伴生对象的名字。

伴生对象的底层实现是HelloScala$。为了观察这个现象,我们在Windows系统下用NotePad来编辑一个scala文件,并用原始的scalac来编译它,会得到两个.class文件:

104_4.png为了查看这两个文件的内容以及差异,我们使用jd-gui.exe对class文件进行反编译:

//----------------------HelloScala.class------------------------//
import scala.reflect.ScalaSignature;

//忽略部分代码
public final class HelloScala
{
  public static void main(String[] paramArrayOfString)
  {
    HelloScala..MODULE$.main(paramArrayOfString);
  }
}
//----------------------HelloScala$.class-----------------------//
import scala.Predef$;

public final class HelloScala$
{
  public static final  MODULE$;

  static
  {
    new ();
  }

  public void main(String[] args)
  {
    Predef$.MODULE$.println("Hello Scala!");
  }

  private HelloScala$()
  {
    MODULE$ = this;
  }
}

观察编译的代码,我们就能发现本质上是HelloScala.class中的主函数实际上是包装了HelloScala$.class中的MODULE$的main实例方法

如何用jd-gui去查看.class文件代码,笔者在之前已经提到过。

为什么用txt打开.class文件会乱码,而打开.java文件却不会乱码?

为什么要进行一个这样的包装过程呢?

Scala的设计者马丁·奥德斯基将程序的静态内容和非静态内容区分开来,他认为静态的内容不应该属于OOP对象的范畴。

譬如Circle类的static变量:Pi,它实际上跟具体的圆对象无关,对圆这个类来说,Pi是一个”貌合神离”的全局变量。

因此设计者将同一个类的非静态部分声明为class:伴生类,将它的静态部分声明为object:伴生对象。(该部分在后续的学习中继续补充)

HelloScala的主函数声明

def关键字表示声明一个方法。如果声明该方法是主函数(程序的入口),则方法(函数)名必须声明为main。这是一个规定,就比如Java的主函数必须为(Public static void main())。

Scala的声明变量特点是参数名在前,类型在后

Array[String]代表这是一个String类型的Array。Scala的[]括号作用与Java的<>相当:用于指代泛型。

def main(args:....):Unit={...}中的:Unit = 代表该函数结构体的返回值是void类型。而Unit也是一个真实存在的一个类。

Scala和Java的编译器有相同的地方,又有很多不同。比如可以使用scala命令来运行javac编译过的.class文件,但反之,用java命令来运行scalac编译过的.class文件,则不一定会执行成功。

注意,运行主函数的类需要声明为object,而非class。就像Java的主函数要在静态域中运行一样,Scala的主函数也在静态域运行,而Scala中,由伴生对象来保存一个类的静态部分

使用Java类来模拟Scala的运行机制

复习Java的两个类修饰符

在此之前,首先复习Java类的两个类修饰符号:public,或者缺省。一个.java文件可以存在多个class,甚至不包含class(比如:创建了空文件,但是什么都没有写)。

一个.java文件内最多只能有一个声明为public class。且声明为public class的名字要与.java文件名称必须相同,而同一个.java内的其它非public class则没有限制。

public class PublicClazz {
    public static void main(String[] args) {}
}

class defaultCLazz{   }

同一个.java文件内声明的多个class可以看作它们在同一个包下,可以相互调用。与该.java文件内的其它class对象也可以调用public属性。但它们对于外部的包则不可见。

在编译时,javac会将同一个.java内的多个class拆分出来,编译出多个.class文件。除了在.java文件中标注为public的class之外,都会被编译成时default类型

然而从习惯上,都是一个.java文件里只封装一个同名class,这会使得整体的架构更加明确。

使用Java代码来复原Scala底层代码

使用java代码来还原Scala的包装过程,这是一个HelloScala.java文件:

package simulation;

//对外使用的HelloScala类。
public class HelloScala {
 public static void main(String[] args) {
   HelloScala$.MODULE$.main(args);
 }
}
class HelloScala${
 static final HelloScala$ MODULE$;
 //在静态域中初始化它。
 static {
   MODULE$ = new HelloScala$();
 }

 public void main(String[] args){
   System.out.println("真正被执行的主函数");
 }
}

这段java程序还原了scala.class文件90%的内容。

这个程序真正执行的是MODULE$的main方法。我们可以注意到,MODULE$被static,final修饰。也就是HelloScala伴生对象的实例,它们本质上都维护同一个MODULE$静态实例,符合单例模式的设计。

在Scala中,通过把变量放置在一个单例对象保管的方式,来实现Java的静态功能,这个专门保存单例对象的类在Scala中称之为伴生对象,它使用一个独立的object关键字来修饰,而非class

下图表示Scala的一个伴生对象HelloScala由HelloScala.classHelloScala$.class共同组成。

104_5.png

参考菜鸟教程中的设计模式:

菜鸟教程:设计模式

Scala的运行方式

1、 .scala文件经scalac编译成.class文件,再运行。
2、 .scala文件直接由scala运行,但是速度很慢,且不会生成.class文件。(我们也几乎不会这么做)

Scala的注意事项

1、 严格区分大小写。
2、 若一行一条语句,则不需要加分号。若一行多条语句,则中间的语句之间需要加分号。
3、 源文件以.scala为拓展名,但在底层都被编译成了.class文件。
4、 Scala的程序执行入口是main函数,主函数运行在伴生对象object中

Scala的字符串输出

Scala支持三种方式来输出字符串。除了Java和C风格的输出外,还引用了Linux风格的$引用方式。注意细节:若使用’$’来引用的话,则字符串前面要加上一个s标识

var string1 : String = "Hello"
var string : String = "Scala"

//与Java的System.out.println无异。
println(string1 + "," + string)

//c语言的格式化输出
printf("%s,%s",string1,string)

//Linux的$引用方式
printf(s"$string,$string1")

如何查看Scala关联的源码?

在刚刚安装完Scala开发插件和SDK时,源码并没有被关联,因此在编程时看不到.scala的底层实现,比较麻烦。在这里先关联源码。

按住Ctrl,单击任何一个Scala类,即可追溯到该类的声明文件,并且IDEA会提示Sources not found。

104_6.png

从官网下载scala-sources-2.xx.x.tar文件夹,解压到SDK的lib目录下,注意,版本要对应。然后再Attach Sources选项中选择关联即可。

在安装之前可以先用scala -version指令确认版本。

Scala文档注释

首先在.scala程序内进行doc风格注释:

object ScalaDocTest {

  /**
    * 此为Scala中的主函数声明。必须要将该主函数声明在伴生对象object中。
    * @param args 运行时参数
    */
  def main(args: Array[String]): Unit = {
    println("This is a main function.")
  }

  /**
    * 该方法是静态的,因为它声明在了伴生对象ScalaDocTest中。
    * @return 返回一个"Hello Scala"字符串。
    */
  def greet():String ={
    return "Hello Scala"
  }

}

在IDEA下可以打开Terminal,默认为项目的根目录。进入到scala文件所在的目录,执行以下命令,可以*.scala选中某个目录下的所有.scala文件:

scaladoc -d {目标路径} {scala文件所在路径}

命令行会提示一句:model contains x ducumentable templates.表示找到x处可以生成文档的地方并生成。

随后可以在指定目录里查看到.scala文件内的文档注释被提取为了html格式。

104_7.png104_8.png

文章永久链接:https://tech.souyunku.com/41998

未经允许不得转载:搜云库技术团队 » Scala之:从零开始的Scala生活

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们