ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Scala基础笔记

2020-01-31 18:03:34  阅读:219  来源: 互联网

标签:case Option val Scala 基础 笔记 println 类型 方法


Scala基础

简介

  1. Scala代码都需要通过编译器转换成字节码在java虚拟机上运行,scala可以无缝调用java代码。

  2. Scala 是面向对象的编程语言,同时也是函数式编程。(fp)

  3. 静态类型语言,定义变量时,需要定义类型, 尽管看起来像是动态类型语言。

  4. 在函数式语言中,函数作为一等公民,可以在任何地方定义,在函数内或函数外,可以作为函数的参数和

    返回值,可以对函数进行组合

  5. 提倡定义不变类型val,对值操作的时候不是修改,而是修改新的产生的值,原来的值保持不变。

  6. 提倡使用尾递归。尾递归即只在尾部调用函数本身,没有其他操作。

repl

read- evalutaion -print- loop

在repl模式下有三个模式

paste模式

:pas/:paste

可以粘贴多行代码

slient模式

安静模式,不会输出每个表达式的类型和值

power模式

这个模式并不针对普通用户,并且 cpu 耗费很高,通常用不着

:help

使用帮助

值与变量定义

val 定义后不可变(scala推荐)

var 定义后可以改变

val a:String = "hello scala"

通常不需要定义变量类型,scala会自动推断。

分清不变引用和不变对象

  1. Scala 里所有变量都是指向变量的引用,变量声明为val 意味着它是个不变引用;
  2. 所有方法参数都是不变引用;
  3. 类参数默认是不变引用
  4. 创建可变引用唯一方法是使用var关键字
  5. HashMap 有可变版和不可变版

常用特殊类型

  1. Any(abstract)
    Any 是所有Scala 类型的父类型,定义了通用方法 equals、hashCode、toStirng。Any有两个子类型AnyRef 和 AnyVal
  2. AnyVal 所有值类型,Scala定义类9种非空值类型
  3. AnyRef(class) 所有引用类型的父类,可以看作是java.lang.Object的别名。
  4. 类型匹配 值类型可以按照下图关系进行转换
    1. 在这里插入图片描述

函数

def + 方法名(参数名 : 参数类型) : 返回类型 = {
  //block内最后一行为返回值

}
  • 当返回值为Unit时可以定义为: def 方法名(参数名 : 参数类型) {}
  • 没有参数的方法可以不带圆括号 例如:“1”.toInt
  • Scala没有静态方法,通过object来实现

单例对象object

单例对象与一个类共享一个名称时,单例对象称为伴生对象,伴生对象与类必须定义在一个源文件中。

变长参数

在参数类型后面加个*

过程(区别过程与函数)

单函数体包含在花括号中,但前面没有等号,那么返回类型就是Unit这样的函 数叫做过程

lazy

单行 val 前面加上lazy 关键字时,它的初始化将被推迟,直到我们首次对它取值。(懒加载)

case class(案例类)

  • 案例类(Case classes)和普通类差不多,非常适合用于不可变数据。
  • 编译器对case类混入了Product特质,编译器对case类增加了copy方法
  • 编译器对case类实现了equals/hashCode/toString等方法
  • 伴生对象中最重要的方法是 unapply 这个方法是在进行构造器模式匹配时的关键。
  • 伴生对象中apply方法则为创建对象提供方便,相当于工厂方法(
  • 伴生对象继承了AbstractFunction,允许接收 Tuple 作为参数构造(即一次性传入多个参数进行构造)
case class A(a: Int, b: Int) 
A.tupled
val t = (100,100)
A.tupled(t)

模式匹配

类似于正则表达式,然后比正则表达式更灵活。

模式

  1. 常量模式
  2. 变量模式
  3. 构造器模式
  4. 通配符模式
  5. 类型模式
  6. 变量绑定模式
  7. 抽取器模式
  8. 序列模式
  9. 元组模式

option

Scala 里提供了 scala.Option 类,Option 可以看做一个容器要么有东西(Some),要么什么东西都没有

不包含任何值的Option 用None 来构建

包含一个值的Option 用Some 的工厂方法来创建。

数组

Array(100) 和 new Array(100) 有非常大的差别,前者表示实例化一个Array ,Array里面包含一个元素

100,后者 表示实例化一个容量为100 的Array,每一个元素都是Null

定长Array

变长ArrayBuffer

nil:空list

初始化&赋值

val array=new array[Int](7)
#两种赋值方法
array(1)=0
array+=0

遍历打印

array foreach println

数组中对象查找

array.filter(_.arrtibute==xxx)

数组元素处理

(1) :: 该方法被称为cons,意为构造,向队列的头部追加数据,创造新的列表。用法为 x::list,其中x为加入到头部的元素,无论x是列表与否,它都只将成为新生成列表的第一个元素,也就是说新生成的列表长度为list的长度+1(btw, x::list等价于list.::(x))

(2) :+和+: 两者的区别在于:+方法用于在尾部追加元素,+:方法用于在头部追加元素,和::很类似,但是::可以用于pattern match ,而+:则不行. 关于+:和:+,只要记住冒号永远靠近集合类型就OK了。

(3) ++ 该方法用于连接两个集合,list1++list2

(4) ::: 该方法只能用于连接两个List类型的集合

3,4区别是什么?

元素遍历

array.map{
      line =>
        println(s"姓名:${line.name},金额:${line.money}")
    }

基本语法

for

  for(i <- 0 to 3) {
        print(i)
      }//0,1,2,3

      for(i <- 0 until 3) {
        print(i)
      }//0,1,2

 for(i <- 1 to 3; j <- 1 to 3 ){ //if(i != j) 够简略
      println(s"i is $i" + s" j is $j")
    }//双重for循环

要推出循环,不能直接使用break语句,需要加入一个包

import scala.util.control.Breaks._
breakable { var n = 10
for(c <- "Hello World") { if(n == 5) break; print(c)
n -= 1
} }

异常处理

try {
      throw new IndexOutOfBoundsException("....")
    } catch {
      case e: IndexOutOfBoundsException => e.printStackTrace()
    }

文件读取

val root = ReadFileDemo.getClass.getResource("/")
val url = new URI(root + "readMe.txt");
//    val f = new File(),所以需要构造URL
    //注意 fromFile 接收的参数是URI
    lazy val words = scala.io.Source.fromFile(url).mkString

    //定义lazy 变量的作用是延迟加载,用到变量的时候才去加载
    println(words)

Option

Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None

getOrElse(parameter)

有就输出,没有就输出parameter(默认值)

extractor

 def extractorMM(it: Student) = it match {
    case Student("李磊",age) => println(age)
    case  _ => println("none")
  }
object Square {
  //unapply方法通常被称为提取方法,这里提取的是一个容器,里面有z的开方
  //Option 是一种容器,有两个子类Some 和 None 要么有值,要么啥都没有
  def unapply(z: Double): Option[Double] = Some(math.sqrt(z))
}

object SquareTestor{
  def main(args: Array[String]) {
    val number = 7.0
//    println(Square.unapply(number))//传统方式调用
//    这样我们无需显式调用unapply方法,而把是它用在pattern match中,让编译器替我们调用它。
    number match {
        //通过StringContext 方法拼接字符串
      case Square(n) => println(s"square root of $number is $n")#符合函数条件
      case _=>  println("nothing matched")
    }
  }

}

函数

模版

def function(parameter:dataType):returnType={
returnParameter
}

模式匹配

def main(args: Array[String]): Unit = {
    println(foo(List("STRING")))
  }
  
  def foo(a: Any): String = a match {
    //non-variable type argument String in type pattern List[String] 
    //(the underlying of List[String]) is unchecked since it is eliminated by erasure
    //只能检查包装,检查不了里面的货物一次 下面这行应当这样写List[_]
    case a: List[Int] => "OK"//只检测是List
    case _ => "fail"
  }

变量绑定

匹配成功后把值绑定给变量

 def main(args: Array[String]) {
    val tree = Tree(TreeNode("root",TreeNode("left", null, null),TreeNode("right", null, null)))
    println(tree.root match {
      case TreeNode(_, leftNode_var@TreeNode("left",_,_), _) => leftNode_var
      //依然是上面的TreeNode,如果我们希望匹配到左边节点值为”left”就返回这个节点的话:
      //即是匹配到了上面的treenode,然后把形如@TreeNode("left",_,_)的treenode绑定给leftnode_var
      //然后返回
      case _ => println("error")
    })
  }
Zunler 发布了21 篇原创文章 · 获赞 7 · 访问量 1万+ 私信 关注

标签:case,Option,val,Scala,基础,笔记,println,类型,方法
来源: https://blog.csdn.net/weixin_42297075/article/details/104126023

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有