scala学习笔记(一)

本文详细探讨Scala中val与var的区別,强调val的不可变性和lazy修饰的特性。讲解了何时选择val,以及for推导式在集合生成中的应用。同时介绍了Scala的数据类型和编程范式,包括函数式编程和方法与函数的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快学scala学习笔记

var和val的区别

val和var的区别

  • 内容是否不变
  • val修饰的变量在编译后,等同于加上final
  • 是否可以有lazy修饰.val修饰的变量还可以用lazy修饰

只有val修饰的变量才能被lazy修饰;使用lazy定义变量后,只有在调用该变量时才会实例化这个变量的值。而且惰性变量只能是不可变变量;

类似方法,先声明,后调用

scala> val a = 10
a: Int = 10
scala> lazy val b = 100
b: Int = <lazy>
scala> b
res2: Int = 100
scala> var c = 10
c: Int = 10
scala> lazy var d = 100
<console>:1: error: lazy not allowed here. Only vals can be lazy
       lazy var d = 100
            ^
scala> def e = 1000
e: Int
scala> e
res3: Int = 1000

使用var 声明一个变量。

  • var修饰的变量,内容和引用都可变

使用val声明一个常量或值

  • val修饰的变量是不可变的,注意不可变的不是内容,而是引用;

    (扩展一下什么是值类型,什么是引用类型,可以使用数组举例,引用不可变,变的是内容。)

    /**可变和不可变?
    可变和不可变,指的是变量本身存的内容,值类型变量存的是数据本身,而引用类型变量存的是数据的引用,
    
    值类型和引用类型?
    值类型与引用类型区别:
    存储方式:直接存储数据本身 vs 存储的是数据的引用,数据存储在数据堆中
    内存分配:分配在栈中 vs 分配在堆中
    效率:效率高,不需要地址转换 vs 效率较低,需要进行地址转换
    内存回收: 使用完后立即回收 vs 使用完后不立即回收,而是交给GC处理回收
    */
    scala> val arr = Array(1,2,3,4,5)
    arr: Array[Int] = Array(1, 2, 3, 4, 5)
    scala> arr = Array(1,2,3)
    <console>:8: error: reassignment to val
           arr = Array(1,2,3)
    scala> arr(0)=10
    scala> arr
    res1: Array[Int] = Array(10, 2, 3, 4, 5)
    

**使用val 还是var **

官方推荐val
使用val的好处:

  • 更安全
  • 代码可读性更高
  • 资源回收更快,方法执行完,val所定义的变量即回收

for循环

如果for循环的循环体以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值

for (i <- 1 to 10) yield i % 3
//将交出Vector(1,2,0,1,2,0,1,2,0,1)

这类循环叫做for推导式(for comprehension)

生成的集合与它的第一个生成器是类型兼容的。

for (c <- "Hello"; i <- 0 to 1) yield (c+i).toChar
//将交出 "HIeflmlmop" 这里的结果是和"Hello"类型兼容的
for (i <- 0 to 1; c <- "Hello") yield (c+i).toChar
//将交出Vector('H','e','l','l','o','I','f','m','m','p') 这里的内容是和 0 to 1 类型兼容的

scala中的数据类型

image-20210822233133414

Unit是值类型,他只有一个实例对象()。

Nothing是所有类型的子类,他没有一个具体的实例对象,一个常见的应用如:抛出异常、程序exit,无限循环等。

Nothing是所有类型的子类,也是Null的子类。Nothing没有对象,但是可以用来定义类型。例如,如果一个方法抛出异常,则异常的返回值类型就是Nothing(虽然不会返回) 。

def get(index:Int):Int = {
    if(x < 0) throw new Exception(...)
    else ....
}

if语句是表达式,有返回值,必然有返回值类型,如果x < 0,抛出异常,返回值的类型为Nothing,Nothing也是Int的子类,所以,if表达式的返回类型为Int,get方法的返回值类型也为Int。

break和continue

Scala里面没有break和continue关键字,推荐使用函数式的风格解决break和continue的功能

//需要导入包
import util.control.Breaks._
//break例子
object scalaTest {
  def main(args: Array[String]): Unit = {
    //break例子
    breakable(
      for(i<-0 until 10) {
        if(i==5){
          break()
        }
        println(i)
      }
    )
  }
}
//continue例子
import util.control.Breaks._
object scalaTest {
  def main(args: Array[String]): Unit = {
    //break例子
      for(i<-0 until 10) {
        breakable{
          if(i==5){
            break()
          }
          println(i)
       }
      }
  }
}

方法和函数

定义方法

定义方法的基本格式是:

def 方法名称(参数列表):返回值类型 = 方法体

def add(x: Int, y: Int): Int = x + y
println(add(1, 2)) // 3
//也可以定义成
//def add(x: Int, y: Int) = x + y
//或者
//def add(x: Int, y: Int){x + y},没有返回值,一定要用大括号把方法体括起来

带有多参数列表的方法:

def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier
println(addThenMultiply(1, 2)(3)) // 9
定义函数

给方法传递一个函数类型的参数:

def foo(f: Int => String) = ...

def bar(f: (Boolean, Double) => List[String]) = ...

函数可以看做是带有参数的表达式。

1,函数的定义方式:

val f1 = ((a: Int, b: Int) => a + b)
val f2 = (a: Int, b: Int) => a + b
val f3 = (_: Int) + (_: Int)
val f4: (Int, Int) => Int = (_ + _)

2,函数的定义方式:

val f1:((Int,Int)=>Int)={(x,y)=>x+y}
val f2:(Int,Int)=>Int =(x,y)=>x+y
方法和函数的区别
  • 方法和函数的定义语法不同

    def 方法名(参数列表):返回类型=方法体

    val 变量 = (函数参数列表)=> 函数体

  • 方法一般定义在某个类、特质、或者object中

  • 方法可以共享使用所在类内的属性

  • Methods of an object can be passed as functions

  • Methods and functions are not the same thing

在函数式编程语言中,函数是“头等公民”,可以调用它,也可以传递它,存放在变量中,或者作为参数传递给另一个函数。

案例:首先定义一个方法,再定义一个函数,然后将函数传递到方法里面

image-20210822235330703
方法转换成函数

把方法作为参数传给另一个方法或者函数的时候,方法被转化成函数

使用神奇的下划线_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值