Scala基础部署数据类型及简单语法

Posted 虎鲸不是鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala基础部署数据类型及简单语法相关的知识,希望对你有一定的参考价值。

Scala基础(一)部署、数据类型及简单语法

概述

官网

Scala是运行在 JVM 上的多范式编程语言,同时支持面向对象编程(OOP)函数式编程(FP)

官网文档可以看到已经有Scala3,但还是要用Scala2(老版本稳定性好):

Scala2下载地址

Scala优点:语法简洁、灵活。是静态编程语言(源码→编译[确定数据类型,避免某些bug]→执行,比起Python这种动态编程语言直接 源码→加载执行 安全)。

官网API

菜鸟Scala教程

部署

安装路径不能有中文空格!!!

Win10部署Scala SDK

先安装JDK1.8,配置环境变量。之前配置过就可以略过。

解压到某个文件夹,安装路最好不要有中文和空格!!!之后win+Q搜索环境变量,即可配置环境变量:

SCALA_HOME=C:\\soft\\scala-2.11.12 
path=%SCALA_HOME%\\bin;


win+R,输入cmd回车,敲scala(启动Scala解释器)验证是否成功:

:quit(这个:必须有)可以退出cmd模式的scala。

Linux部署Scala SDK

上传、解压、配置环境变量、shell敲scala验证,流程与Win10部署差不多。

cd /export/software/
rz
tar -zxvf scala-2.11.12.tgz -C /export/server
cd /export/server/
scp -r scala-2.11.12 node2:$PWD
scp -r scala-2.11.12 node3:$PWD
vim /etc/profile

末尾插入:

#SCALA_HOME
export SCALA_HOME=/export/server/scala-2.11.12
export PATH=$PATH:$SCALA_HOME/bin

保存后:

source /etc/profile

敲scala测试是否成功:

[root@node1 server]# scala
Welcome to Scala 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_241).
Type in expressions for evaluation. Or try :help.

scala> print("hello scala")
hello scala
scala> :quit

再配置node2和node3的环境变量并测试,不再赘述。

IDEA部署Scala插件

当然不可能一直用cmd来做Scala,idea更方便些。。。插件中搜索Scala,自动安装的插件和本机兼容性好。

选Plugins,搜索scala:

当然安装下载最多的。。。安装完成后点Restart IDE或者手动关闭重启都可以:

重启后新建个项目:

简单使用,选Scala空白项目,后期可以使用Maven实现Scala与Java联合编程。

首次启动没有Scala的SDK,需要点Create:

如果搜不到,说明环境变量还没有刷新,需要重启计算机才行。中间随便点一下(变蓝)后OK即可点Finish。

在src中右键→New→Scala Class,就可以创建新的Scala类。当然为了不影响主体,也可以新建module方便测试:

选Object后会发生这种事。。。Scala严禁随意使用空格:

使用psvm当然是不行的,要使用main

object HelloWorld 
  def main(args: Array[String]): Unit = 
    print("Hello World")
  

首次ctrl+shift+f10运行会很慢:

Hello World
Process finished with exit code 0

编译后发现编译出了.class字节码文件:

反编译试试:

不明觉厉,但是可以看出这个class后缀的文件和正常的Java文件差不多,说明Scala是使用JVM的。

语法基础

Scala解释器

学习Scala基本语法可以考虑使用Scala解释器,不需要多余内容,可以像Linux命令一样,一次执行一条代码,马上可以看到结果。比起用idea写类更方便。

定义变量

Scala和Java的语法不太一样。标准套路:

val/var 变量名:变量类型 = 初始值

val定义的是不可重新赋值的变量,var定义的是可以重新赋值的变量。变量名在前,变量类型在后(变量类型可以省略,Scala可以自动推测),末尾不需要;(+;也不会报错,但是没什么用)。

//定义val,自动推测数据类型,数据的值不可修改
scala> val str0001="haha1"
str0001: String = haha1
scala> str0001="haha2"
<console>:12: error: reassignment to val
       str0001="haha2"

//定义var,自动推测数据类型,数据的值可以修改
scala> var str0002="hehe1"
str0002: String = hehe1
scala> str0002="hehe2"
str0002: String = hehe2

//区分大小写
scala> val str0003:String = "0003"
str0003: String = 0003
scala> val str0003:string = "0003"
<console>:11: error: not found: type string
       val str0003:string = "0003"

//没有""双引号包裹值会报错

当某些变量的数据量比较大,且不需要马上加载到JVM内存,就需要惰性赋值,需要的时候才加载到JVM内存。套路:

lazy val 变量名 = 表达式
//惰性赋值只能使用val,不能用var
scala> lazy var SQL1 = "select"
<console>:1: error: lazy not allowed here. Only vals can be lazy
lazy var SQL1 = "select"

//惰性赋值的val可以更改值
scala> val SQL1 = "select"
SQL1: String = select
scala> val SQL1 = "select1"
SQL1: String = select1
scala> SQL1
res1: String = select1

//使用"""三引号修饰字符串,可以换行输入
scala> lazy val SQL2="""
     | SELECT
     |     *
     | FROM
     |     table1;
     | """
SQL2: String = <lazy>
scala> SQL2
res4: String =
"
SELECT
    *
FROM
    table1;
"

Scala中也有类似C#中使用$拼接字符串的方式,但是毕竟不是同一种语言,插值表达式的套路有所不同:

scala> val name = "张三"	//支持中文字符串
name: String = 张三
scala> val age = 20
age: Int = 20

scala> val personinfo = s"name = $name,age = $age"	//插值表达式
personinfo: String = name = 张三,age = 20
scala> println(personinfo)							//输出变量
name = 张三,age = 20
scala> println(s"$personinfo>>$1+2"+"haha")		//花括号内可以是运算式、对象.方法调用,还可以使用+连接字符串
name = 张三,age = 20>>3haha

数据类型

由于需要使用JVM,基本数据类型与Java的包装类数据类型基本一致。

基础类型类型说明
Byte8位有符号整数
Short16位有符号整数
Int32位有符号整数
Long64位有符号整数
Char16位无符号Unicode字符
StringChar类型的序列(字符串)
Float32位单浮点数
Double64位双浮点数
Boolean布尔,true或者false

Scala所有数据类型都是大写字母开头。一般让Scala自动推测数据类型就好。

类型说明
Any所有类型的父类
AnyVal所有数值类型的父类
AnyRef所有对象类型(引用数据类型)的父类
Unit表示无值(void),用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()
Nullnull或者空引用
Nothing所有类型的子类(抛出的一次返回值是Nothing)

运算符

类别操作符
算数运算符+、-、*、/
关系运算符>、<、==、!=、>=、<=
逻辑运算符&&、||、!
位运算符&、||、^、<<、>>

Scala中没有++--运算符:

scala> 5
res14: Int = 5

scala> 5++
<console>:12: error: value ++ is not a member of Int
       5++
        ^

scala> 5--
<console>:12: error: value -- is not a member of Int
       5--

Scala使用==!=比较字符串的值是否一致,使用eq方法比较2个对象的引用值:

scala> val str1 = "aaa"
str1: String = aaa

scala> val str2 = str1+""
str2: String = aaa

scala> str1 == str2
res12: Boolean = true		//字符串内容相同

scala> str1.eq(str2)
res13: Boolean = false		//字符串的引用不同

块表达式

Scala也是使用花括号来表示一个代码块(代表这一大坨是一个整体)。块表达式有值:

scala> val a=
     | 1+1
     | 3
     | 5
     | 
<console>:12: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
       1+1
        ^
<console>:13: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses
       3
       ^
a: Int = 5

显然块表达式的值就是最后一个表达式的值。如果只有一个表达式,显然可以省略。

条件表达式

对应其它语言的if判断的分支结构。Scala有if/else,但是没有三元表达式(可以自己定义方法用if/else实现)。也有类似Java和C#中Switch/Case的功能。

scala> val a=20
a: Int = 20
scala> val b = if(a!=20) 5 else 10	//实现if/else
b: Int = 10

scala> var c = a match 			//需要使用match实现switch/case
     | case 10 => 10
     | case 20 => 21
     | case 30 => 32
     | case _  => 0
     | 
c: Int = 21

if/else可以嵌套多层,也可以多分支,不赘述。

循环表达式

while循环和java相同:

scala> var a = 5
a: Int = 5
scala> while(a>=0) a=a-1;print(a)		//使用;分割同一行的语句
43210-1

当然也可以使用while(true)的死循环。。。

for循环的套路则有所不同:

scala> val array1 = Array(11,22,33)
array1: Array[Int] = Array(11, 22, 33)

scala> for( i <- array1) println(i)		//可以遍历数组/集合/表达式
11
22
33

scala> for(i <- 1 to 5) print(i)		//to是包含后边的参数
12345
scala> for(i <- 1 until 5) print(i)		//until是不包含后边的参数
1234
scala> for(i <- 1 to 5 if i%2 != 0) print(i)	//守卫条件
135

scala> val b = for( i <- array1) yield i*10+1	//for推导式
b: Array[Int] = Array(111, 221, 331)

scala> array1.map(_*10+1)				//函数式编程更高效
res24: Array[Int] = Array(111, 221, 331)

可以直接遍历数组/集合/表达式,还可以使用守卫条件for推导式,比Java的for循环强大。

Scala没有BreakContinue关键字,好在提供了Breaks类,可以模拟出相同的效果:

import scala.util.control.Breaks._

object BreakDemo 
  def main(args: Array[String]): Unit = 
    //模拟break
    breakable
      for (i <- 1 to 10)
        if(i>6) break()
        else print(i)
      
    

    println("*****-----华丽的分割线-----*****")

    //模拟continue
    breakable
      for (i <- 1 to 100)
        if(i%10==0) break()
        else print(i)
      
    

  


使用idea比较方便,当然cmd里也可以导包。。。

方法与函数

Java类中封装的一大坨功能模块叫方法(method直译),C和Lua中封装的功能模块叫函数(function直译),貌似区分并不明确。但是Scala中方法和函数有极大的区别。在Scala这种函数式编程语言中,函数是头等公民(极其重要)。

方法

方法定义是这种套路:

def 方法名(变量名1:变量类型=默认值1,变量名2:变量类型=默认值2):返回类型 =
    //方法体

可以省略很多内容:

scala> def method1(a:Int,b:Int)=a+b		//双参数方法
method1: (a: Int, b: Int)Int
scala> method1(1,2)
res3: Int = 3

scala> def method2=print("haha")		//无参方法
method2: Unit
scala> method2
haha

scala> def method3(a:Int)(b:Int)=a+b	//另一种格式的双参数方法
method3: (a: Int)(b: Int)Int
scala> method3(1)(2)
res34: Int = 3

但是递归方法(例如:求阶乘)不能省略:

scala> def method1(a:Int) = if(a<1) 1 else method1(a-1)*a
<console>:13: error: recursive method method1 needs result type
       def method1(a:Int) = if(a<1) 1 else method1(a-1)*a
                                           ^

scala> def method1(a:Int):Int = if(a<1) 1 else method1(a-1)*a
method1: (a: Int)Int

scala> method1(5)
res6: Int = 120

调用无默认值的方法时不给参数会报错:

scala> def method1(a:Int) = if(a<1) 1 else method1(a-1)*a
scala> method1()
<console>:13: error: not enough arguments for method method1: (a: Int)Int.
Unspecified value parameter a.
       method1()

scala> def method1(a:Int=5):Int = if(a<1) 1 else method1(a-1)*a		//给定默认参数
method1: (a: Int)Int

scala> method1()												//不给参数时调用默认参数
res11: Int = 120

带名参数的调用和C语言差不多。

Scala支持变长参数

def 方法名(参数名1:参数类型*):返回类型=
    //方法体

事实上可以省略很多内容:

scala> def method1(a:Int*)=a.sum
method1: (a: Int*)Int

scala> def method1(a:Int*)=a.sum
method1: (a: Int*)Int

scala> val array1 = Array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
array1: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23)

scala> method1(array1)
<console>:14: error: type mismatch;		//数组与可变参数不匹配
 found   : Array[Int]
 required: Int
       method1(array1)
scala> method1(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
res14: Int = 276

scala> method1(5)
res1: Int = 5

scala> method15					//只有1个参数时可以使用花括号调用
res2: Int = 5

scala> method11,5					//不止1个参数时不可以使用花括号调用
<console>:1: error: ';' e

以上是关于Scala基础部署数据类型及简单语法的主要内容,如果未能解决你的问题,请参考以下文章

Scala之option类型及偏函数使用异常处理正则表达式

大数据学习06 Scala的基础语法

Scala简介及基础语法

Scala基础语法

Scala基础语法

2021年大数据常用语言Scala:基础语法学习 数据类型与操作符