Scala 初识 (一)

官网:https://www.scala-lang.org/

概述

Scala编程语言是一款多范式的编程语言,即纯面向对象又是函数式编程的一款高级语言;支持类型推断(推断)可以在复杂的应用避免一些不必要的错误;Scala的应用程序运行在JVM(java 虚拟机)之上,可以无缝的和Java语言进行互操作;并且提供了一个规模庞大的生态系统,可以简化复杂应用的开发;

特点

  • 无缝和Java进行互操作
  • 类型推导(推断)
  • 天生支持并发和分布式开发
  • 功能强大的特质(trait)类
  • 模式匹配(值、类型、元素、元素类型等)
  • 高阶函数(函数是Scala编程语言中的一等公民)

环境搭建

准备工作:需要JDK1.8以及以上
安装:安装 scala版本是2.11.12
win + r -> cmd -> scala -version 检测是否安装成功

IDEA 集成Scala插件
plugins 中搜索 scala 下载安装,打开项目设置添加外部依赖
IDEA 添加Scala依赖

使用

Scala 窗口命令使用

REPL: R (读取) E (评估) P(打印) L(循环)
win + r -> cmd -> scala 回车进入Scala 的命令窗口模式

scala> 1+1
res1: Int = 2

scala> 2+2
res2: Int = 4

注意: res2: Int = 4 声明变量语法: 变量名 : 类型 = 值

传统用法

手动书写scala的源文件,先编译后解释执行;

scala源文件.scala —> scalac 源文件.scala —> .class(字节码文件) —> scala .class字节码文件名

object HelloWorld{
	// scala主函数
	def main(args:Array[String]):Unit = {
		println("Hello World")
	}
}

编译运行

D:\>scalac HelloWorld.scala

D:\>scala HelloWorld
Hello World

变量和常量

Scala 与 Java有着相同的数据类型,下表列出了 Scala 支持的数据类型:

数据类型描述
Byte8位有符号补码整数。数值区间为 -128 到 127
Short16位有符号补码整数。数值区间为 -32768 到 32767
Int32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
Float32位IEEE754单精度浮点数
Double64位IEEE754单精度浮点数
Char16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
String字符序列
Booleantrue或false
Unit表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
Nullnull 或空引用
scala> 3*4
res5: Int = 12

scala> 1*0.5
res6: Double = 0.5

scala> true
res7: Boolean = true

scala> false
res8: Boolean = false

scala> "abc"
res9: String = abc

scala> 'c'
res10: Char = c

注意:

  1. scala中变量的类型支持自动推导: 整数(Int) 、小数(Double) 其它(略)
  2. scala中基本类型scala.* ,如:scala.Int或scala.Double; scala中的字符串类型:java.lang.String

声明变量

语法:var 变量名 : 类型 = 值

# 1. 完整写法
scala> var a : Int = 10
a: Int = 10

scala> println(a)
10

# 2. 简化写法
scala> var b = 20
b: Int = 20

scala> var c = 30L
c: Long = 30

scala> var d:Long = 40
d: Long = 40

scala> var c = 30L
c: Long = 30

scala> var f : Float = 30.1f
f: Float = 30.1

scala> var date = new java.util.Date()
date: java.util.Date = Mon Jan 06 11:44:58 CST 2020

注意:

  • 变量的值是允许重复更改的
  • 声明变量时,不添加类型则使用类型推导;如果添加类型信息,则使用指定的类型;

声明常量

语法:val 常量名:类型 = 值

scala> val a1:Int = 10
a1: Int = 10

scala> a1 = 20
<console>:12: error: reassignment to val
       a1 = 20
          ^

注意:

  • 常量只允许赋值一次
  • 常量值类型值不可变,引用类型是地址不可变
  • 在scala中除过特殊的需求外,建议使用常量;

运算符

  • 赋值运算符: =
  • 关系运算符: > 、< 、<= 、>= 、!=、 ==
  • 逻辑运算符:&& (与)、 || (或) 、!(非)
  • 位运算符:& 、| 、~ 、^、<<、 >>、 >>>
  • 算术运算符:+、-、*、/、%

注意:scala没有++--语法,但是依然保留了+=-=


# 1. 从右向左执行 将10赋值给变量a1
scala> var a1 = 10
a1: Int = 10

# 2. 关系运算符 比较判断 得到Boolean值
scala> 1 > 2
res13: Boolean = false

scala> 1 < 2
res14: Boolean = true

scala> 2 <= 2
res15: Boolean = true
# 注意: scala做到严格意义上的万物皆对象  运算符实际上都是对象中的方法
scala> 1.<(2)
res21: Boolean = true

scala> 1 + 1
res22: Int = 2

scala> 1.+(1)
res23: Int = 2

# 3. 逻辑运算符
scala> true || false
res26: Boolean = true

scala> !true
res27: Boolean = false

scala> !false
res28: Boolean = true

# 4. 算数运算符
scala> 1.*(2)
res34: Int = 2

scala> 3/6
res35: Int = 0

scala> 6/2
res36: Int = 3

scala> 6./(2)
res37: Int = 3

scala> 6%4
res38: Int = 2

scala> 6.%(4)
res39: Int = 2

# 5. 位运算   (二进制运算)
# &&&  逻辑 "与" 不具备短路运算
# & 位运算 相同的二进制位 同时为1 则结果为1
# | 有一个为1则结果为1 不同为0
# ^ 异或 相同为0,不同为1
# ~ 按位取反
# >> 右移
# << 左移
# >>> 无符号右移  不论是负数还正数 移动后都是正数

# 300000011 >> 1 00000001
# 500000101
# 3 & 5 = 1   
# 3 | 5 = 7
# 3 ^ 5 = 00000110 = 6
# ~3 = 11111100 = -4
# 3 >> 1

类型转换

值类型可以进行转换

值类型可以按照下面的方向进行转换
Scala Type Hierarchy

scala> var b1 :Byte = 10
b1: Byte = 10

scala> var s1:Short = b1
s1: Short = 10

scala> var i1:Int = s1
i1: Int = 10

scala> var i2:Int = 'c'
i2: Int = 99

scala> b1 = i1
<console>:13: error: type mismatch;
 found   : Int
 required: Byte
       b1 = i1
            ^

Scala 类型层次结构

Scala 基本数据类型

  • Any是所有类型的超类型,也称为顶级类型。它定义了一些通用的方法如equalshashCodetoStringAny有两个直接子类:AnyValAnyRef
  • AnyVal代表值类型。有9个预定义的非空的值类型分别是:DoubleFloatLongIntShortByteCharUnitBooleanUnit(类似于java中的void)是不带任何意义的值类型,它仅有一个实例可以像这样声明:()。所有的函数必须有返回,所以说有时候Unit也是有用的返回类型。
  • AnyRef代表引用类型。所有非值类型都被定义为引用类型。在Scala中,每个用户自定义的类型都是AnyRef的子类型。如果Scala被应用在Java的运行环境中,AnyRef相当于java.lang.Object
  • Nothing是所有类型的子类型,也称为底部类型。没有一个值是Nothing类型的。它的用途之一是给出非正常终止的信号,如抛出异常、程序退出或者一个无限循环(可以理解为它是一个不对值进行定义的表达式的类型,或者是一个不能正常返回的方法)。
  • Null是所有引用类型的子类型(即AnyRef的任意子类型)。它有一个单例值由关键字null所定义。Null主要是使得Scala满足和其他JVM语言的互操作性,但是几乎不应该在Scala代码中使用。我们将在后面的章节中介绍null的替代方案。
scala> :paste
// Entering paste mode (ctrl-D to finish)

val list: List[Any] = List(
  "a string",
  732,  // an integer
  'c',  // a character
  true, // a boolean value
  () => "an anonymous function returning a string"
)

// Exiting paste mode, now interpreting.

list: List[Any] = List(a string, 732, c, true, <function0>)

scala> list.foreach(n => println(n))
a string
732
c
true
<function0>

Scala 输入输出

  • 输出

打印输出值,需要使用print或者println函数,println(s" = ${}")
也有带有C风格格式化字符串的函数 printf("Hello, %s! You are %d years old.\n","Fred",44) // Hello, Fred! You are 44 years old.

  • 输入

输出值,使用readLine函数从控制台读取一行输入 readDoublereadByte等不同类型的输入

分支语句

类似于Java的分支语句

if语句
if(布尔表达式){
    // 代码块
}

如:

scala> if(age >= 18){
     |  println("成年人")
     | }
成年人

scala> if(age >= 18) println("成年人")
成年人

scala> var m = if(age >= 18) println("成年人")
成年人
m: Unit = ()

scala> var n = if(age >= 18){
     | 	println("成年人")
     | 	1
     | }
成年人
n: AnyVal = 1

scala> var x = if(age >= 18){ println("成年人"); 1; }
成年人
x: AnyVal = 1
if…else… 语句
if(布尔表达式){
    // true 
}else{
    // false
}

scala> if(age > 18){
     |   println("成年人")
     | }else{
     |   println("未成年人")
     | }
未成年人
if…else if…else语句
if(布尔表达式1){
    // true
}else if(布尔表达式2){
    // true
}...else{
    // false
}

var age = 18

scala> if(age > 60){
     |   println("老年人")
     | }else if(age > 40){
     |   println("中年人")
     | }else if(age >= 18){
     |   println("青年人")
     | }else{
     |   println("未成年人")
     | }
青年人
match匹配语句

替换java switch...case语句

scala> age match{
     | 	case 18 => println("18岁")
     | 	case 20 => println("20岁")
     | 	case _ => println("默认的")
     | }
18岁

scala> var age = 25
age: Int = 25

scala> age match{
     |  case a1 if(a1 >= 40) => println("中年人")
     |  case a2 if(a2 >= 20) => println("青年人")
     |  case _ => println("其它")
     | }
青年人

注意:

  • scala的match匹配语句,不会存在匹配穿透问题;
  • scala的match匹配语句,default默认的匹配规则使用的是_
  • scala的match匹配语句,目前只使用到了值的匹配

循环语句

while语句
while(布尔表达式){
    // 循环体内容
}

# 计算1+2+3...+100整数之和 5050
var m = 1
var sum = 0
while(m <= 100){
    sum += m
    m += 1
}
println(sum)
do…while语句
do{
    // 循环体
}while(布尔表达式)

# 计算1+2+3...+100整数之和 5050
var m = 1
var sum = 0
do{
    sum += m
    m += 1
}while(m <= 100)
println(sum)
for循环语句
for(遍历产生的临时变量 <- 数值区间对象 | 集合 | 数组){
    // 循环体
}

scala> 1 to 10
res72: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8
, 9, 10)

scala> 1 until 10
res73: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> 1 to 10 by 2
res74: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)

# 计算1+2+3...+100整数之和 5050
var sum = 0
for(n <- 1 to 100){
    sum += n
}
println(sum)

注意:

  • 数值区间对象,代表的是一个Range对象,构建方法有:n to m(包含起始n和结束m) 或n until m(包含起始但不包含结束m) , 设定步长增幅
嵌套for循环
# 九九乘法表
for(m <- 1 to 9){
	for(n <- 1 to m){
        print(n+"*"+m+"="+(m*n) +"\t")
    }
    println()
}

1*1=1
1*2=2   2*2=4
1*3=3   2*3=6   3*3=9
1*4=4   2*4=8   3*4=12  4*4=16
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49
1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64
1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81

# 注意: 多重循环可以写在一个forfor(m<- 1 to 9; n <- 1 to m){
    print(n+"*"+m+"="+(m*n) +"\t")
    if(m == n) {
        println()
    }
}
for循环中if守卫
# 遍历展示 1 to 10 数值区间的奇数,并且不能是5
for(n <- 1 to 10 by 2){
    if(n != 5) println(n)
}

# 另外一种if写法 守卫语法
for(n <- 1 to 10 by 2 if n != 5 && n != 7){
    println(n)
}
continue和break

注意:scala中没有continuebreak关键字;

  • continue建议使用if守卫代替;
  • break 中止循环;可以使用scala特殊类Breaks类实现等价效果
import scala.util.control.Breaks

object HelloWorld {
  // 主函数
  def main(args: Array[String]): Unit = {
 // 可能会发出终止信号的代码 包裹起来
    Breaks.breakable {
      for (n <- 1 to 10) {
        // 终止循环 1 2 3 4
        if (n == 5) {
          Breaks.break()
        }
        println(n)
      }
    }
  }
}

//--------------------------------------------------
scala> import scala.util.control.Breaks
import scala.util.control.Breaks

scala> :paste
// Entering paste mode (ctrl-D to finish)
// 可能会发出终止信号的代码 包裹起来
Breaks.breakable {
      for (n <- 1 to 10) {
        // 终止循环 1 2 3 4
        if (n == 5) {
          Breaks.break()
        }
        println(n)
      }
    }

// Exiting paste mode, now interpreting.

1
2
3
4

yield关键字

for 循环中的 yield 会把当前的元素缓存下来,在遍历结束后返回一个新的集合

  • 首先会将yield 表达式的值会被加入存放到一个缓冲区中
  • 在遍历结束之后,会返回一个基于缓冲区的新集合,类型为Vector
  • 新集合的元素的类型和遍历集合的类型是一致的
  • yield在使用时,只有一行代码,代码块不能使用{}
// 2  4  6  8  => [6,12,18,24]
val v1 = for(n <- 1 until 10 if n %2 ==0) yield n*3
for(m <- v1){
    println(m)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值