zoukankan      html  css  js  c++  java
  • 【Scala学习之一】 Scala基础语法

    环境
      虚拟机:VMware 10
      Linux版本:CentOS-6.5-x86_64
      客户端:Xshell4
      FTP:Xftp4
      jdk1.8
      scala-2.10.4(依赖jdk1.8)
    spark-1.6

    Scala是一种混合功能编程语言,类似java,运行于JVM,集成面向对象编程和函数式编程的各种特性。
    (1)Scala可以与Java互操作:它用scalac这个编译器把源文件编译成Java的class文件,从Scala中调用所有的Java类库,也同样可以从Java应用程序中调用Scala的代码
    (2)Spark是专为大规模数据处理而设计的快速通用的计算引擎,而spark就是scala编写的。
    (3)对比Groovy和Scala:Groovy的优势在于易用性以及与Java无缝衔接,Scala的优势在于性能和一些高级特性


    一、数据类型


    二、变量和常量
    定义变量:var,值可修改;
    定义常量:val,值不可修改

    var a:Int=10
    var a=10
    val a=10

    注意:
    (1)scala 中一行代码后可以写“;”也可以不写,会有分号推断机制。多行代码写在一行要用分号隔开。
    (2)a: Int ": Int" 是变量的类型,可以写也可以不写,不写会自动推断变量类型

    三、访问修饰符
    私有的 private
    受保护的 protected
    有明确使用修饰符则自动归为公共成员 Public


    四、运算符
    跟java差不多,但是没有自增++、自减--运算符
    https://www.yiibai.com/scala/scala_operators.html


    五、流程控制
    1、分支判断

    val age =18 
    if (age < 18 ){
    println("no allow")
    }else if (18<=age&&age<=20){
    println("allow with other")
    }else{
    println("allow self")
    }

    2、循环
    (1)to和until 的用法(不带步长,带步长区别)

    /**
    * to和until
    * 例:
    * 1 to 10 返回1到10的Range数组,包含10
    * 1 until 10 返回1到10 Range数组 ,不包含10
    */
    
    println(1 to 10 )//打印 Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    println(1.to(10))//与上面等价,打印 Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    println(1 to (10 ,2))//步长为2,从1开始打印 Range(1, 3, 5, 7, 9)
    println(1.to(10, 2)) //Range(1, 3, 5, 7, 9)
    
    println(1 until 10 ) //不包含最后一个数,打印 Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
    println(1.until(10))//与上面等价 Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
    println(1 until (10 ,3 ))//步长为2,从1开始打印,打印Range(1, 4, 7)

    (2)for
    (2.1)for循环

    for( i <- 1 to 10 ){
    println(i)
    }

    (2.2)多层for循环

    //可以分号隔开,写入多个list赋值的变量,构成多层for循环
    //scala中 不能写count++ count-- 只能写count+
    var count = 0;
    for (i <- 1 to 10; j <- 1 until 10) {
    println("i=" + i + ",    j=" + j)
    count += 1
    }
    println(count);
    
    //例子: 打印小九九
    for (i <- 1 until 10; j <- 1 until 10) {
    if (i >= j) {
    print(i + " * " + j + " = " + i * j + "    ")
    
    }
    if (i == j) {
    println()
    }
    
    }

    (2.3)for循环中可以加条件判断,可以使用分号隔开,也可以不使用分号

    //可以在for循环中加入条件判断
    for (i <- 1 to 10; if (i % 2) == 0; if (i == 4)) {
    println(i)
    }

    (2.4)scala中不能使用count++,count—只能使用count = count+1 ,count += 1
    (2.5)for循环用yield 关键字返回一个集合

    var result = for (i <- 1 to 10) yield i;
    println(result);//Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    result.foreach { x => println(x) }//增强for循环

    (3)while循环,while(){},do {}while()

    /**
    * while 循环
    */
    var index = 0
    while (index < 100) {
    println("第" + index + "次while 循环")
    index += 1
    }
    index = 0
    do {
    index += 1
    println("第" + index + "次do while 循环")
    } while (index < 100)

    六、类和对象
    类:
    class是scala中的类;
    类可以传参,传参就有了默认的构造函数;
    重写构造,第一行要调用默认的构造类可以传参;
    class类属性自带getter ,setter方法;
    使用class时要new ,并且new的时候,class中除了方法不执行,其他都执行;
    同一个包下,class的名称不能相同。

    对象:
    object是单例对象,相当于java中的工具类,可以看成是定义静态的方法的类;
    object不可以传参数。另:Trait不可以传参数;
    使用object时,不用new;


    注意:
    (1)建议类名首字母大写 ,方法首字母小写,类和方法命名建议符合驼峰命名法。
    (2)如果在同一个文件中,object对象和class类的名称相同,则这个对象就是这个类的伴生对象,这个类就是这个对象的伴生类。可以互相访问私有变量。

    package com.wjy
    
    class Person(xname: String, xage: Int) {
    var name = Person.name
    val age = xage
    var gender = "m"
    def this(name: String, age: Int, g: String) {
    this(name, age)
    gender = g
    }
    
    def sayName() = {
    "my name is " + name
    }
    
    }
    
    object Person {
    var name="zhangtiantang";
    def main(args: Array[String]): Unit = {
    
    val person = new Person("wagnwu",10,"f")
    println(person.age);
    println(person.sayName())
    println(person.gender)
    }
    
    }

    七、函数

    1、函数定义
    (1)函数定义用def,函数的参数 要写类型,不写类型不可以。
    (2)函数的返回值类型可以不写,会自动推断,但在递归函数中或者函数的返回值是函数类型的时候 不能省略
    (3)scala会将函数体中最后一行计算的结果当做返回值返回
    (4)可以写“return”,写了return要显式的声明方法体的返回类型。
    (5)定义函数时,如果不写“=”,那么无论方法体中最后一行计算的结果返回是什么,都会被丢弃,返回Unit
    (6)函数体可以一行搞定,那么方法体的“{... ...} ” 可以省略不写

    def fun (a: Int , b: Int ) : Unit = {
       println(a+b)
     }
    fun(1,1)
        
    def fun1 (a : Int , b : Int)= a+b
        println(fun1(1,2)) 

    2、递归函数

    def fun2(num :Int) :Int= {
    if(num ==1)
    num
    else 
    num * fun2(num-1)
    }
    print(fun2(5))


    3、包含参数默认值的函数
    (1)默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。
    (2)如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称。

    def fun3(a: Int = 10, b: Int) = {
    println(a + b)
    }
    fun3(b = 2)     

    4、可变参数个数的函数
     多个参数用逗号分开

    def fun4(elements: Int*) = {
    var sum = 0;
    for (elem <- elements) {
    sum += elem
    }
    sum
    }
    println(fun4(1, 2, 3, 4))
    
    def fun5(elms: String*)={
    //简化1:foreach 下划线_就代表每一个元素
    elms.foreach { println(_)}
    //简化2:foreach println后面不跟任何东西 即可打印每一个参数
    elms.foreach { println}
    }
    
    fun5("a","b","c","d","e","f")

    5、匿名函数
    (1)有参匿名函数
    (2)无参匿名函数
    (3)有返回值的匿名函数
    (4)可以将匿名函数返回给val定义的值--闭包
    (5)匿名函数不能显式声明函数的返回类型

    //有参数匿名函数
    val value1 = (a: Int) => {
    println(a)
    }
    value1(1)
    //无参数匿名函数
    val value2 = () => {
    println("我爱wjy")
    }
    value2()
    //有返回值的匿名函数
    val value3 = (a: Int, b: Int) => {
    a + b
    }
    println(value3(4, 4))

    6、嵌套函数

    def fun5(num: Int) = {
    def fun6(a: Int, b: Int): Int = {
    if (a == 1) {
    b
    } else {
    fun6(a - 1, a * b)
    }
    }
    fun6(num, 1)
    }
    println(fun5(5))

    7、偏应用函数
    偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。

    def log(date: Date, s: String) = {
    println("date is " + date + ",log is " + s)
    }
    
    val date = new Date()
    log(date, "log1")
    log(date, "log2")
    log(date, "log3")
    
    //想要调用log,以上变化的是第二个参数,用下划线表示,可以用偏应用函数处理
    val logWithDate = log(date, _: String)
    logWithDate("log11")
    logWithDate("log22")
    logWithDate("log33")

    8、高阶函数
    函数的参数是函数,或者函数的返回类型是函数,或者函数的参数和函数的返回类型是函数的函数。

    //函数的参数是函数
    def f(v1: Int, v2: Int): Int = {
    v1 + v2
    }
    def hightFun(f: (Int, Int) => Int, a: Int): Int = {
    f(a, 100)
    }
    println(hightFun(f, 1))
    
    //函数的返回是函数
    //1,2,3,4相加
    def hightFun2(a: Int, b: Int): (Int, Int) => Int = {
    def f2(v1: Int, v2: Int): Int = {
    v1 + v2 + a + b
    }
    f2
    }
    println(hightFun2(1, 2)(3, 4))
    
    //函数的参数是函数,函数的返回是函数
    def hightFun3(f: (Int, Int) => Int): (Int, Int) => Int = {
    f
    }
    println(hightFun3(f)(100, 200))
    println(hightFun3((a, b) => { a + b })(200, 200))
    //以上这句话还可以写成这样
    //如果函数的参数在方法体中只使用了一次 那么可以写成_表示
    println(hightFun3(_ + _)(200, 200))

    9、柯里化函数
    可以理解为高阶函数的简化

    def fun7(a: Int, b: Int)(c: Int, d: Int) = {
    a + b + c + d
    }
    println(fun7(1, 2)(3, 4))

    八、闭包
    闭包是一个函数,它返回值取决于在此函数之外声明的一个或多个变量的值。

    object Demo {
    def main(args: Array[String]) {
    println( "multiplier(1) value = " + multiplier(1) )
    println( "multiplier(2) value = " + multiplier(2) )
    }
    var factor = 3
    val multiplier = (i:Int) => i * factor
    }

    参考:
    Scala开发环境安装配置
    Scala基础语法

  • 相关阅读:
    Microsoft Dynamics CRM 2011 配置好的IFD环境 怎么制作证书?
    Microsoft Dynamics CRM 2011 Plugin中PluginExecutionContext.InputParameters["Target"]中的Target是从哪来的?
    编程写一个方法时,注意方法中传参数的数量最好不要超过5个,超过5个怎么办?可以用struct或class,或一个字典类
    Microsoft Dynamics CRM 2011 常用JS 按F12 改动窗体上数据的方法
    JS 实现轮播图
    JS晃动的花朵
    定时器的应用 盒子的移动
    JavaScript 经典实例
    累加 9*9乘法表 阶乘
    函数方法
  • 原文地址:https://www.cnblogs.com/cac2020/p/10541695.html
Copyright © 2011-2022 走看看