Scala知识总结

本文围绕Scala语言展开,介绍了其数据类型,如Any、AnyVal等,还阐述了惰性求值、Block等特性。详细讲解了函数的多种形式,包括柯里化、偏函数等,以及List、Range等数据结构的使用方法,同时涉及构造器、继承、apply方法等面向对象编程的内容。

Scala数据类型

    Any是所有类的父类
    AnyVal是所有基本类型的父类,AnyRef是所有Java里引用类型和所有自定义Scala类的父类
    Null是所有引用类型的子类,Nothing是所有Scala类的子类

    数值类型:byte, short, int, long, double, float
    布尔类型:true, flase
    字符(串)类型:Char, String
    Unit:相当于Java中的void

惰性求值

    在变量第一次被使用的时候才求出变量的值
    适用场景
        如果在后续的程序中可能不会被用到,我们可以把该变量定义为惰性值

Block(代码块)

    用于组织多个表达式
    Block整体也是一个表达式,其值为Block中的最后一个表达式的值

if

    if是表达式,会返回一个值

match表达式

    express match{
        case p1 => val1
        case p2 => val2
        ...
        case _ => valn
    }

for语句

    val l = List(1,2,3,4,5)
    for(i <- l; if(i%2 == 0)) println(i)  或者
    for{i <- l; if(i%2 == 0)} println(i)
    可以利用for语句遍历List并产生一个新的List
        val newL = for{i <- l; if(i%2 == 0)} yield(i)

    语法糖

//for循环嵌套循环并倒序输出
for(i <- (1 to 3).reverse; j <- (1 to 2).reverse){
    println(i+" "+j)
}

输出
3 2
3 1
2 2
2 1
1 2
1 1
//用if条件过滤值
for(i <- 1 to 3; j <- 1 to 2; if(i%2 != 0 && j%2 != 0)){
    println(i+" "+j)
}

输出
1 1
3 1
//用yield关键字生成产生一个序列
val seq = for(i <- 1 to 10;if(i > 5))yield i

结果
seq: scala.collection.immutable.IndexedSeq[Int] = Vector(6, 7, 8, 9, 10)

Scala中的break和continue

import scala.util.control.breakable

//break例子
breakable{
    for(i <- 1 to 10){
        if(i == 2)
            break
        println(i)
    }
}

//break例子
for(i <- 1 to 10){
    breakable{
        if(i%2 == 0)
            break
        println(i)
    }
}

以上是Scala中的break和continue语句,注意breakable语块的位置

foreach()

    传递一个函数,对序列中的每一项调用这个函数。这个函数不会改变序列
        val l = List(1,2,3,4,5)
        l.foreach(_*10)

    还可以在遍历时指定一个临时变量,例如
        l.foreach{
            i=>print(i); println(" "+ (i+2))
        }

函数

    函数类型

        函数类型的格式为A=>B,表示一个接受类型A的参数,并返回B类型的函数

    函数赋值

        def max(x:Int, y:Int) = if(x>y) x else y
        方式1 val maximize = max _
        方式2 val maximize:(Int, Int) => Int = max
        方式3 val maximize = max(_, _)

    柯里化

        柯里化函数把具有多个参数的函数转换为一条函数链,每个节点上是一个单独的参数
            例如
            def add(x:Int)(y:Int) = x+y
            注意在调用的时候要写成 add(1)(2)而不是add(1,2)

    偏函数

        方式1
            def func(x:Int, y:Int) = y%x == 0
            val f = func(2, _:Int)
        方式2(柯里化)
            def func(x:Int)(y:Int) = y%x == 0
            val f = func(2) _


    Scala两种求值策略

        Call By Value 对函数实参求值,且仅求值一次(常用)
            如. def func(x:Int) = x
        Call By Name 函数实参每次在函数体内被用到都会求值
            如. def func(x:=>Int) = x

    尾递归函数

        函数中所有递归形式的调用都出现再函数的末尾。当编译器检测到一个函数是尾递归函数时,它就覆盖掉当前的活动记录而不是在栈中创建一个新的。
        函数需要用@annotation.tailrec修饰
            例如.
            @annotation.tailrec
            def factorial(n:Int, m:Int) = if(n <= 0) m else factorial(n-1, m*n)

    副作用

        函数改变实参的值的行为称为函数对变量产生副作用
        如
            var a = 1; def func(x:Int) = {x += 1; x}; func(a);
            这里在调用函数之后改变了a原来的值,说明函数func对变量a产生了副作用

    
    无参函数什么时候加括号什么时候不加?

        无副作用的函数省略括号,有副作用的函数添加括号

List

    List是一个不可变的单链表

    用双冒号(::)作为元素连接符,最后一个元素是Nil,可生成一个列表
    用三冒号(:::)作为连接符可连接两个List
    用双加号(++)可连接其他集合类型,如Set,Map
    用(:+)可向列表中单独添加元素

    List方法

    head
        用来获取List中的第一个元素
    tail
        用来获取List中的除第一个元素外的所有元素
    isEmpty
        用来判断List是否为空
    distinct
        返回一个不含重复元素的列表
    drop(n)  <--------> dropRight
        返回一个除去列表前n个元素的列表
    filter
        参数是一个布尔类型的函数,用来过滤List中的值
    partition
        将元素分成两个列表构成的元组
    reverse
        将元素顺序反转
    slice(m, n)
        返回列表[m,n)之间的元素
    sortBy(func)
        func是一个函数,根据func来排序
    sorted
        按自然值对核心Scala类型列表排序
    max
        返回列表中的最大值,与之对应的有min
    contains(n)
        查找列表中是否有n元素
    exists(func)
        如果列表中有一个元素使func返回true则返回true
    forall(func)
        如果列表中的所有元素都使func返回true则返回true否则返回false
    splitAt(n)
        按数字n列表拆分
    take(n)  <--------> takeRight
        取列表中的前n个元素
    takeWhile
        参数是一个布尔类型的函数,同样用来过滤,不过函数在遇到第一个使布尔函数返回false的值时执行结束
    list1.zip(list2)
        将l1与l2中的元素一一对应连接成一个列表,遇到Nil就结束
        如List(1,2,3).zip(List(11,22))返回List((1,11),(2,22))
    map
        用来处理集合里的每一个元素,并返回处理后的集合
    flatMap
        用来把两层嵌套列表整合映射成一个列表
    faltten
        用来把两层嵌套列表整合成一个列表
    reduce, reduceLeft, reduceRight
        给定一个归约函数,从列表中第一个元素(Right是右边第一个)开始归约列表,返回一个计算值
    fold, foldLeft, foldRight
        给一个归约函数和一个定起始值,归约列表,,返回一个计算值
    scan, scanLeft, scanRight
        给一个归约函数和一个定起始值,归约列表,,返回一个计算过程各个值的列表

Range

    to
        用关键词to连接两个数形成一个包含两端的Range,加by可控制步长
            例如.
            1 to 10 by 2 //->Range(1,3,5,7,9)
    until
        用关键词to连接两个数形成一个左闭右开的Range,加by可控制步长
            例如.
            1 until 5 //->Range(1,2,3,4)

Stream

    Stream是一个惰性List,只有第一个值是可见的
    用双冒号(#::)作为元素连接符,最后一个元素是Stream.empty,可生成一个Stream
    collection.toStream方法可获得一个Stream

tupple

    多个值用逗号分隔再加上圆括号就是一个tupple,两个值形成的tupple成为pair(可单独用'x->y'的形式产生pair)
    用下划线+位置来访问tupple中的元素,注意这里的位置坐标比通常的数组坐标大1

Map[K,V]

    用Map(pairs)可获得一个Map

    获取一个元素可用m(key)或者m.get(key),在key不存在的情况下前者会抛异常

    添加新元素用+跟pair(s)
        例如
        var map = Map(1->10, 2->20)
        map += (3->30)
        添加多个
        map =+ ((3->30),(4->40))
   把另外一个Seq中的元素加到Map中
        例如
        var map = Map(1->10, 2->20)
        map = map ++ List(3->30, 4->40)
    删除元素与上面的类似,
        map -= (1), 删去多个map -= (1,2)
    常用方法
        keys
            返回 Map 所有的键(key)
        values
            返回 Map 所有的值(value)
        isEmpty
            在 Map 为空时返回true
        contains(key)
            查看 Map 中是否存在指定的key

构造器

    主构造器
    主构造器的参数列表直接写在类名(Class)后面。在一个Scala类中,除了参数,方法以外的代码都是主构造器的内容
    从构造器
    从构造器的定义是以def this(...)开始,并且内部第一条语句要调用主构造器
        class ConstructorTest(var name:String,var age:Int){
                def this(name:String){
                    this(name,20)
                }
            }

继承

    在Scala中,一个类可以使用extends关键字扩展最多一个其他类,另外可以用override关键字覆盖所继承的方法。
        class A{
            def hi = "Hello from A"
            override def toString = getClass.getName
        }
        class B extends A{
            override def hi = "hi from B "+super.hi
        }

apply方法

    apply方法实际上是一个快捷方式,可以使用小括号除法功能而不需要方法名
        class multiplier(factor:Int){
            def apply(input:Int) = factor * input
        }
     
        val mul = new multiplier(10)
        println(mul(3))
    list取元素也是调用了apply方法,list(0),list(2),...

object

    object是一个类类型,只能有不超过1个实例,在面向对象设计中称为一个单例。对象不用new关键字创建实例,只需要按名直接访问,相当于静态类。

trait

    trait是一种支持多重继承的类。类,对象都只能扩展不超过一个类,但是可以同时扩展多个trait。相当于java里的接口,但是在trait中可实现方法体。

type

    type相当于声明一个类型别名,通常用于声明某种复杂类型,或用于定义一个抽象类型

implicit

    通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值