scala安装与scala编程基础1

一、scala概述

  1. 编程语言的开发范式

    a. 面向过程
    b. 面向对象
    c. 函数式编程

  2. 函数式编程概述

    函数式编程:

     将所有复杂的问题的解决 拆分为若干函数的处理 每一个函数可以去实现一部分功能 
     利用很多次函数的处理 最终解决问题。
    

    函数式编程相对于面向对象编程 更加的抽象,好处是:

     1. 代码可以非常的简洁 
    
     2. 更多的采用常量而不是变量来解决问题 这样额外带来的好处 在线程并发时 可以减少甚至杜绝 
     	多线程并发安全问题 特别适合于应用在处理高并发场景 分布式场景下的问题 
     				
     3. 函数式编程并不是面向对象编程的发展,而是另外一种解决问题的思路,两者之间也并没有绝对
     	的好坏之分,在不同的场景中各有各的优缺点。
    
  3. Scala概述

     1. Scala是一种函数式编程的语言 同时具有面向对象编程的特点。
     
     2. Scala是基于JVM运行的:
     	scala 是完全兼容java的,其实scala就是在java语言的基础上增加了一层编码的 “壳” 让程序人员
     	可以通过函数式编程的方式来开发程序。
     	
     	Scala程序编写出.scala文件,需要先编译为.class文件,最终在jvm中运行:
     		.java  --> .class --> 字节码
     		.scala --> .class --> 字节码
     由于scala最终被编译为.class 所以其实本质上还是java 所以在scala中可以任意的调用java的api。
    

二、Scala安装配置和使用(Window下)

  1. 安装

     1. 前提条件:安装jdk并配置JAVA_HOME环境变量 (使用jdk1.8)
    
     2. 安装scalashell:
     	双击运行scala-2.11.7.msi按照提示安装
     
     3. 配置环境变量
     	将scala安装目录下的bin目录配置到path环境变量中
     
     4. 安装spark
     	将spark-2.0.1-bin-hadoop2.7.tgz解压,将解压路径下的bin目录配置到path环境变量中
    
  2. 测试

     win+R,输入cmd,进入dos命令窗口,运行spark-shell,出现如下界面则安装成功,有其他的报错
     不用管		
    

    结果

  3. 使用idea创建Scala项目

     1. 在idea中下载插件Scala,然后重启
    

    插件

     2. 创建新的Scala项目
    

    创建scala项目

    第二步

     这样就创建了一个普通的Scala项目
    

更加详细的创建方法:https://blog.csdn.net/qq_35826412/article/details/82187881

三、Scala语法

  1. 常量和变量

     变量:可以在程序执行过程中进行修改
     常量:一旦被赋值就不能再进行更改了
     
     在java中变量用的比常量要多的多
     但是在scala中更多的应用也更应该主动去应用常量
     
     声明变量要用var关键字
     //1.变量声明
     var str1:String = "abc";
     var str2 = "def";
     str2 = "xyz";
     
     val关键字用来声明常量
     //2.常量声明
     val str3:String = "abc";
     val str4 = "def";
     //str4 = "xyz";//报错
    
  2. 基本的数据类型

    a. 基本数据类型共有9种

     Byte Short Int Long Float Double Char Boolean String
    
     这9种基本数据类型除了String是属于java.lang包以外,其它八种都归属scala包下,在scala中,
     java.lang和scala包都会自动引入,所以在程序中不需要导入就可以直接使用以上9种基本数据类型。
     
     以上9种基本数据类型的用法基本和java中一致。
    

    b. 富包装器

     针对于以上九种基本数据类型,scala还提供了它们的富包装器类型,这9种基本数据类型可以在必
     要时自动的转换为其对应的富包装器类型,使用更多的属性和方法,这个过程就是自动的封箱拆箱
     的过程。
     		scala.runtime.RichByte
     		scala.runtime.RichShort
     		scala.runtime.RichInt
     		scala.runtime.RichLong
     		scala.runtime.RichChar
     		scala.runtime.RichString
     		scala.runtime.RichFloat
     		scala.runtime.RichDouble
     		scala.runtime.RichBoolean
     装箱就是  自动将基本数据类型转换为包装器类型;拆箱就是  自动将包装器类型转换为基本数据类型
    
  3. 操作符

     Scala中没有真正意义上的操作符,操作符即方法,方法即操作符
    

    a. 操作符即方法

     	scala中操作符 也可以像使用方法那样去使用
     	   val num1 = 3 + 2
     	   val num2 = 3.+(2)
     	   println(num1)
     	   println(num2)
     	   val num3 = 3 * 2;
     	   val num4 = 3.*(2);
     	   println(num3)
     	   println(num4)
    

    b. 方法即操作符

     scala中方法 也可以像使用操作符那样去使用
     		   
     val str1 = "abcdefg";
     val c1 = str1.charAt(2);
     val c2 = str1 charAt 2;
     println(c1)
     println(c2)
      
     val str2 = "abcdefghijklmn"
     val r1 = str2.substring(2, 5);
     val r2 = str2 substring (2,5)
     println(r1)
     println(r2)
      
     val str3 = "abcdefg";
     val r3 = str3.toUpperCase();
     val r4 = str3 toUpperCase;
     println(r3)
     println(r4)
    

    c. scala中操作符(函数)的优先级

     scala中的操作符(函数)是有优先级的区分的,优先级由操作符(函数)的首字符决定:
     		
     		* / %
     		+ -
     		:
     		= !
     		< >
     		&
     		^
     		|
     		所有字母
     		所有赋值操作符
     也就是说,多个操作符连续运算(函数连续执行)的过程中,优先级要由首字符来确定,优先级越
     高,越要优先执行,优先级相同的情况下,再遵循由上到下 由左到右的顺序依次执行,如果有小括
     号,则小括号内的内容优先级最高。
     	
     	这样的一个优先级规则,解决了scala中四则运算顺序问题:
    

    d. 特殊运算符 冒号 的用法

     scala中以冒号结尾的方法是一种特殊的函数,不同于普通的函数由左操作数调用传入右操作数,
     这种方法是右操作数调用传入左操作数。
    

    e. 操作符类型

     i. 中缀操作符
     	中缀操作符 指操作符在两个操作数之间。
     	3.+(2) 等同 3 + 2
     ii. 后缀操作符
     	后缀操作符 指 操作符在唯一的操作数之后
     	str1 toUpperCase  等同  str1.toUpperCase();
     iii. 前缀操作符
     	前缀操作符 指 操作符在唯一的操作数之前 
     	前缀操作符只有四种 + - ! ~
     	前缀操作符特殊的地方在于,转换为方法时,不能直接转,而要转换为 unary_符号 形式
         val n1 = -3  等同  val n1 = 3.unary_-
         val n2 = +5  等同  val n2 = 5.unary_+
    
  4. 控制结构

     scala中的内建控制结构其实并不算多 以够用为主 因为可以自建控制结构
    

    a. if判断

     scala中的if的用法基本和java中一致,不同之处在于,scala中的if可以带有返回值
     		   
     val num = 99
     val r1 = if(num<10){
      	"哈哈"
     }else if(num<100){
       	"呵呵"
     }else{
       	"嘻嘻"
     }
     println(r1)
    

    b. while , do…while 循环

     scala中的while 和 do..while的用法和java中基本一致。不可带有返回值。
     		 
     var i = 0;
     var sum = 0;
     while(i <= 10){
       sum += i;
       i += 1;
     }
     print(sum)
    
     while和do..while不可避免的会使用到外界变量,以及很有可能要用到产生额外影响的操作,破坏函
     数的封闭的特性,所以scala中通常不建议使用while do..while实现循环。通常推荐 使用递归 来实现
     循环。
    

    d. for循环

     //i. 增强for
     		   
     val l1 = List(1,3,5,7,9);
     for(n <- l1){
             println(n)
     }
    
     //ii. 普通for	 
     
     for(i <- 1 to 10){
             println("abc"+i)
     } 
    
     //iii. 过滤for(可以在循环条件后面添加过滤条件)
     		    
     //案例:遍历0到100的偶数
     for(i <- 0 to 100; if i % 2==0){
             println(i)
     }
     //案例:遍历0到100的偶数 过滤出其中大于30小于80的数]
     for(i <- 0 to 100; if i % 2==0;if i>30;if i<80){
             println(i)
     }
    
     //iv. 嵌套for
     		  
     //案例:实现九九乘法表
     for(i <- 1 to 9){
       for(j <- 1 to i){
         print(j +" * "+ i +" = "+i*j +" ")
       }
       println()
     }
      
     for(i <- 1 to 9; j <- 1 to i){
             print(j +" * "+ i +" = "+i*j +" ")
     }
    
     //v. 流间变量绑定
     		   
     //--流间变量定义
     for(i <- 1 to 9; j <- 1 to i;val str = "\r\n"){
             print(j +" * "+ i +" = "+i*j + str)
     }
     for(i <- 1 to 9; j <- 1 to i;val str = if (i==j) "\r\n" else " "){
             print(j +" * "+ i +" = "+i*j + str)
     }
    
     //vi. 制造新的集合
     	for循环默认的返回值类型是Unit,即不能带回返回值
     	但是可以通过yield关键字将每次循环的的最后一个表达式的值组成集合返回
     		  
     //--yield关键字创建新集合
     val r = for(i <- 1 to 9;j <- 1 to i) yield {
             j +" * "+ i +" = "+i*j
     }
     println(r)
    

    e. try…catch…finally捕获异常

     scala中继承了java的异常机制 提供了 程序中产生意外情况时 处理的机制抛出异常的过程和java中
     基本一致通过throw关键字进行 throw xxxException()一旦抛出可以当场捕获处理或接着向上抛,捕
     获异常是通过 try catch finally来实现的
     		    
     try{
       val i = 1/0;
     }catch{
       case t: NullPointerException => println("空指针异常!") 
       case t: IOException => println("IO异常!")
       case t: RuntimeException => println("其他运行时异常!")
       case t: Throwable  => println("其他异常或错误!")
     }finally{
       println("无论如何都执行 finally")
     }
    
     // try..catch..finally可以带有返回值				    
     val r = try{
       val i = 1/0;
     }catch{
       case t: NullPointerException => "空指针异常!"
       case t: IOException => "IO异常!"
       case t: RuntimeException => "其他运行时异常!"
       case t: Throwable  => "其他异常或错误!"
     }finally{
       "无论如何都执行 finally"
     }
     println(r)
    
     try..catch..finally中,finally块中的返回值 不会改变 try或catch块中返回值的值,这点和java
     中是不同的
    

    f. match匹配

     // 类似于java中的switch..case语法,可以实现 匹配操作
     		
     val str = "def"
     val r = str match {
       case "abc" => "哈哈哈" 
       case "def" => "呵呵呵"
       case "ghi" => "嘻嘻嘻"
       case _ => "啦啦啦"
     }
     println(r)
    

    g. continue和break

     scala中没有continue和break,如果想要实现  类似continue和break的操作,只能通过布尔类型的变
     量来控制循环条件
     		  
     //案例:将0到100的奇数进行累加  但如果累加值超过了50,则不再进行累加,求最后的累加的值
     var x = 0;
     var sum = 0;
     var  flag = true;
     while(x < 100 && flag){
             if(sum>50){
                     flag = false;
             }
             if(x % 2==0){
             //
             }else{
                     sum += x;
             }
             x += 1;
     }
     print(sum)
    
     这种方式 可以避免continue和break的使用,但是引入了外部布尔类型的变量,破坏了函数封闭的
     特点同样不推荐.官方推荐的做法,是通过递归的方式来实现:
     	
     def mx(i:Int,sum:Int):Int={
       if(sum>50 || i >100) sum;
       else if(i % 2 ==0) mx(i+1,sum)
       else mx(i+1,sum+i)
     }
     val r = mx(0,0)
     println(r)
    

四、函数

  1. 函数的概念

    函数是一段具有特定功能的代码的集合由函数修饰符 函数名 函数参数列表 函数返回值声明函
    数体组成可以将一段代码组合成函数,在后续需要时调用函数,执行代码,实现相应功能
    
  2. 函数的定义 - 普通函数定义

    格式:

     [override][final][public/private/protected] def 函数名(参数列表):返回值声明 = 
     {函数体}
     
     通过def关键字声明一个函数
     def前面可以通过private protected来控制其访问权限 没有public 不写默认就是public的也可跟
     上override final等关键字修饰
     
     def sum1(n1:Int,n2:Int):Int={
             return n1 + n2;
     }
    

    在函数体中return关键字在不造成歧义的情况下可以省略,如果省略,则函数会将最后一个表达式的值作为返回值返回

     def sum1(n1:Int,n2:Int):Int={
     n1 + n2;
     }
    

    大部分的情况下,函数可以自动推断返回值的类型,所以返回值类型的声明可以省略

     def sum1(n1:Int,n2:Int)={
             n1 + n2;
     }
    

    如果函数体只有一行内容,则包裹函数体的大括号可以省略

     def sum1(n1:Int,n2:Int)= n1 + n2;
    

    如果返回值的类型是Unit,则 :Unit= 可以省略

     def sum1(n1:Int,n2:Int){
         println(n1 + n2)
     }
    
  3. 函数的定义 - 函数直接量定义
    格式:

     (参数列表) => {函数体}
     
     可以直接使用函数直接量快速定义一个函数
     (n1:Int,n2:Int)=>{n1 + n2}
     
     如果函数体只有一行内容,则包裹函数体的大括号 可以省略
     (n1:Int,n2:Int)=>n1 + n2
     
     如果函数的参数类型可以自动推断,则函数参数类型声明可以省略
     (n1,n2)=>n1 + n2 //此处报错,并不是写法有问题,而是没有办法推断参数类型,所以报错
     
     如果函数的参数列表中只有一个参数,则在不引起歧义的情况下,包裹参数类型声明的小括号可以省略
     str:String=>str.toUpperCase()
    
  4. 函数的使用 - 成员方法

    函数在scala中共有四种用法:成员方法 本地方法 函数值 高阶函数

    scala中将函数作为类的一个成员,就称为函数称为了类的成员方法
    /**
     * 函数功能1 : 作为类的成员方法使用
     */
    class Person{
      private val name:String = "";
      private val age:Int  = 0;
      def say(){
        println("说...")
      }
      def eat(food:String){
              println("吃..."+food)
      }
    }
    
  5. 函数的使用 - 本地方法
    函数在scala中共有四种用法:成员方法 本地方法 函数值 高阶函数

    scala中可以在函数内部再定义函数,这种用法称之为:函数用作本地方法
    
    def eat(food:String){
      def cook(food:String)={
         "熟的"+food;
      }
      println("吃..."+cook(food))
    }
    
  6. 函数的用法 - 函数值
    函数在scala中共有四种用法:成员方法 本地方法 函数值 高阶函数

    函数本身可以理解为是一个对象,而函数名是指向这个对象的一个引用,所以可以将函数任意赋值给其他引用.
    
    def sum(n1:Int,n2:Int):Int={
      return n1 + n2;
    }
    val sum2 = sum(_,_);    
    val r = sum2(2,3)
    print(r)
    
    也可以直接将一个函数直接量赋值给引用,从而通过引用调用该函数
    
    val sum3 = (n1:Int,n2:Int)=>{n1+n2}
    val r = sum3(2,3)
    println(r)
    

ps:高级函数下次在说

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值