Scala基础部署数据类型及简单语法
Posted 杀智勇双全杀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala基础部署数据类型及简单语法相关的知识,希望对你有一定的参考价值。
Scala基础(一)部署、数据类型及简单语法
概述
官网:
Scala是运行在 JVM 上的多范式编程语言,同时支持面向对象编程(OOP)和函数式编程(FP)。
官网文档可以看到已经有Scala3,但还是要用Scala2(老版本稳定性好):
Scala优点:语法简洁、灵活。是静态编程语言(源码→编译[确定数据类型,避免某些bug]→执行,比起Python这种动态编程语言直接 源码→加载执行 安全)。
部署
安装路径不能有中文和空格!!!
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的包装类数据类型基本一致。
基础类型 | 类型说明 |
---|---|
Byte | 8位有符号整数 |
Short | 16位有符号整数 |
Int | 32位有符号整数 |
Long | 64位有符号整数 |
Char | 16位无符号Unicode字符 |
String | Char类型的序列(字符串) |
Float | 32位单浮点数 |
Double | 64位双浮点数 |
Boolean | 布尔,true或者false |
Scala所有数据类型都是大写字母开头。一般让Scala自动推测数据类型就好。
类型 | 说明 |
---|---|
Any | 所有类型的父类 |
AnyVal | 所有数值类型的父类 |
AnyRef | 所有对象类型(引用数据类型)的父类 |
Unit | 表示无值(void),用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成() |
Null | null或者空引用 |
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没有Break
与Continue
关键字,好在提供了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> method1{5} //只有1个参数时可以使用{}花括号调用
res2: Int = 5
scala> method1{1,5} //不止1个参数时不可以使用{}花括号调用
<console以上是关于Scala基础部署数据类型及简单语法的主要内容,如果未能解决你的问题,请参考以下文章