• Scala极速入门


    摘要 当面向对象遇到函数式编程,这就是Scala。简练的语言描述与简单的例子相辅相成,希望能够对大家学习Scala有所帮助。 
    scala 入门 
    
    
    
    定义 
    
    Scala语言是一种面向对象语言,同时又结合了命令式(imperative)和函数式(functional)编程风格。官网描述:Object-Oriented Meets Functional(面向对象遇到函数式编程)。 
    
    安装 
    
    下载地址http://www.scala-lang.org/download/
    
    当前版本2.11.4
    
    设置环境变量
    
    export SCALA_HOME=/home/mupeng/Hadoop/scala-2.11.4 
    export PATH=$SCALA_HOME/bin:$PATH  
    
    如果是修改的profile,执行source /etc/profile,使环境变量立即生效。 
    
    检测安装是否成功命令 scala -version,如果出现以下内容,证明安装成功。 
    
    scala -version 
    Scala code runner version 2.11.4 -- Copyright 2002-2013, LAMP/EPFL  
    
    Scala解释器 
    
    直接输入scala,就进入scala解释器
    
    scala 
    Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35). 
    Type in expressions to have them evaluated. 
    Type :help for more information.  
    
    先来两个例子,熟悉以下scala解释器 
    
    scala> 1+2 
    res0: Int = 3  
    
    结果被命名为res0,Int指结果类型,3指计算结果
    
    
    scala> println("hello scala") 
    hello scala  
    
    输出hello scala
    
    变量 
    
    Scala中的变量有两种var和val(val类似于Java中final,值不可改变)
    
    scala> var hello = "hello world"
    
    hello: String = hello world
    
    scala可以根据赋值内容推算出变量类型。Scala中的数据类型都是对象。
    
    函数 
    
    Scala是面向对象语言同时也是函数式编程语言,因此函数在Scala语言中的地位同对象、变量一样。使用scala函数注意一下几点:
    
    1) 函数参数写在类型之前,中间用逗号隔开;
    
    def helloScala = { 
        println("Hello Scala!") 
    }  
    
    2) 函数都有返回结果,无需使用return,函数内最后一个表达式作为返回结果返回。helloScala函数的返回类型为Unit,表示该函数不返回任何有意义的值(相当于Java中的void)。 
    
    3) 函数参数可以给定默认值。
    
    def hello(name : String = "Scala") : String = { 
        return "Hello : " + name 
    }  
    
    4) 函数的参数都是val类型,执行过程中不能被改变。(函数式编程的特点,只计算结果,不改变参数)
    
    5) 定义方法还有如下方式
    
    def add = (x : Int, y : Int) => x + y
    
    打印结果print(add(1, 2));  
    
    def add2(x : Int)(y : Int) = x + y
    
    打印结果print(add2(1)(2))
    
    循环 
    
    在了解循环之前,我们先要知道Scala不支持i++和++i,需要使用i+=1来实现加一。
    
    while循环
    
    var i=0 
    while (i < args.length) { 
      println (args(i)) 
      i+=1 
    }  
    
    for循环 
    
    for (arg <-args) 
      println(arg)  
    
    for参数里面同样支持if判断,比如输出1——10中的偶数
    
    for (i <- 1 to 10 if i % 2 == 0)  
      println(i)  
    
    foreach 
    
    args.foreach(arg => println(arg))  
    
    因为参数只有一个,表达式也只有一个,可以简写为
    
    args.foreach(println)  
    
    Array与List 
    
    创建数组有两种方式
    
    val greetStrings = new Array[String](3)  
    greetStrings(0) = "Hello" 
    greetStrings(1) = ", " 
    greetStrings(2) = "world!
    "  
    
    或者
    
    ?
     1 val numNames = Array("zero", "one", "two")  
    
    注意与Java不同的是:数组的第零个元素是greetStrings(0),不是greetStrings[0]。
    
    Array长度不可变,但是它的值可变。
    
    List长度与值都不可变。
    
    val list1 = List(1, 2) 
    val list2 = List(3, 4) 
    val list3 = list1 ::: list2  //list3结果为(1,2,3,4) 
    val list4 = 0 :: list3       //list4结果为(0,1,2,3,4)  
    
    这里有两个操作 ::: 连接两个List
    
    :: 右操作符,将一个新元素放到List的最前端。
    
    类与对象 
    
    1. 定义类
    
    class Person { 
      var email = "abc123@126.com" // 变量,var声明会生成getter和setter方法 
      var name : String = _ // 变量, _起到占位符的作用 
      val age = 10;         // 常变量,val声明只会生成getter 
      private val gender = "male" //只能在类内部使用 
    }  
    
    缺省访问级别是public,一个源文件中可以有多个class,都是public的。
    
    2. 主构造器
    
    class Student(var name : String, val number : String) { 
      println("主构造器!") 
    }  
    
    1)主构造器直接跟在类名后面,主构造器的参数最后会被编译成字段。
    
    2)主构造器执行的时候,会执行类中所有的语句。
    
    3)如果主构造器参数声明时候不加val或者var,就相当于private 
    
    3. 从构造器
    
    class Student(var name : String, val number : String) { 
      println("主构造器!") 
      var gender : String = _ 
      def this(name : String, number : String, gender : String) { 
        this(name, number) 
        this.gender = gender 
      } 
    }  
    
    1)从构造器定义在类内部,方法名为this
    
    2)从构造器必须先调用已经存在的构造器
    
    4. 继承:继承而来的字段不需要加var或者val
    
    class UniversityStudent(name : String, number : String, val major : String) extends Student(name, number) { 
      ...... 
    }  
    
    注意:重写父类的字段或方法要在前面加上override关键字
    
    5. 抽象类(abstract class)与特质(trait)
    
    1)抽象方法不需要加关键字,只有声明,没有具体实现。
    
    2)可以声明抽象字段,也就是没有初始值。
    
    3)子类重写父类的抽象方法或者抽象字段,不需要加override
    
    trait特质可以理解为可以有具体实现方法的接口,类可以通过with关键字混入(mix-in)特质,同时它的对象也可以混入特质。 
    
    Scala程序的执行入口是提供main方法的独立单例对象。同样也可以给一个单例对象混入App特质,去继承App特质中的main方法.
    
    6. apply方法 
    
    1)对象的apply方法
    
    class ApplyTest { 
      println("Test") 
    } 
     
    object ApplyTest { 
      def apply() = new ApplyTest 
    } 
     
    // 调用方法 
    val a = ApplyTest() // 类名+括号,调用对象的apply方法  
    
    上面例子中一个调用apply方法,生成一个新的对象。(绝大多数apply方法都是这样去用)
    
    apply方法就是Scala提供的一个语法糖,对象的apply方法在scala里面非常常用
    
    例如:
    
    val arr = Array(1, 2, 3) 
     
    实际调用的是 
     
    val arr = Array.apply(1, 2, 3)  
    
    以下是Array对象的apply方法源码
    
    object Array extends FallbackArrayBuilding { 
     
       ... 
        
       /** Creates an array of `Int` objects */ 
      // Subject to a compiler optimization in Cleanup, see above. 
      def apply(x: Int, xs: Int*): Array[Int] = { 
        val array = new Array[Int](xs.length + 1) 
        array(0) = x 
        var i = 1 
        for (x <- xs.iterator) { array(i) = x; i += 1 } 
        array 
      } 
       
      ... 
     
    }  
    
    2)类的apply方法
    
    class ApplyTest { 
      def apply() { 
        println("APPLY Method") 
      } 
      println("Test") 
    } 
     
    val a = new ApplyTest 
    a() // 对象名+括号,调用类的apply方法  
    
    7.单例
    
    用object替换class,其它的跟定义类类似。
    
    当单例对象与类共享同一个名字时,该对象称作类的伴生对象。
    
    与Java对比 
    
    如果用作服务器端开发,Scala的简洁、灵活性是Java无法比拟的;如果是企业级应用开发、Web开发,Java的强大是Scala无法匹敌的。我们不用一种语言的优势去抨击另一种语言的短板,所以不要说Java与Scala孰优孰劣,更不要说谁将要取代谁,二者本来就是互补关系。
    
    总结 
    
    scala语言的知识点有太多太多,在一篇博客中不可能做到一一列举。本文只是列举了常用的的几点,希望对正在学习scala的人有所帮助。
    
    相关博文:Scala快速排序的实现分分钟掌握快速排序 
    
    Spark入门博文 Spark初探 
    
    出处http://my.oschina.net/mup/blog/363436?from=20150111
  • 相关阅读:
    array_merge() 用法
    session_unset 与 session_destroy 区别
    关联模型中
    TP框架中分页类的使用
    ajax验证用户名是否被注册 ; ajax提交form表单
    点击图片img提交form表单
    输入框蓝光特效
    搭建owncloud私有云
    小米路由器3-R3 刷固件
    mysql的sql_mode合理设置
  • 原文地址:https://www.cnblogs.com/zendu/p/4981356.html
Copyright © 2020-2023  润新知