zoukankan      html  css  js  c++  java
  • scala快速学习笔记(二):控制结构,类和对象

    IV.控制结构

    1.if/else

    除基本用法外,if/else语句能用来赋值,进而代替?:运算符。这得益于在Scala中,每个语句块都有值,就是该语句块最后一个语句的值。请看下面的代码。

    def abs(x: Int) = if(x < 0) -x else x

    2.与If语句不同,While语句本身没有值,即整个While语句的结果是Unit类型的()。

     PS:scala中赋值语句也没有值。

    3.用于迭代一个集合的for语句,格式为for(item <- collection)。一些collection举例:

    0 to list.length - 1
    0 until list.length
    val list = List("Tom", "Jach", "Jimmy", "Abby")

    • 嵌套for循环  直接分号隔开就行。
    for(i <- 0 to 1; j <- 1 to 2; k <- 2 to 3) {
        println("i = %d, j = %d, k = %d".format(i, j, k))
      }
    • 条件for循环 例如下面代码,i带有条件 i % 2 == 0,这意味着,仅有满足这个条件的i才会被循环执行。
    for{i <- 0 to 5 
        if i % 2 == 0 
        j <- 1 to 2} {
      println("i = %d, j = %d".format(i, j))
    }
    • 中途绑定变量
    //引入了变量lower,这与通常我们定义变量的方式相比,只是少了val。这个变量在for表达式中和循环体中都可以使用。
    val list = List("Html", "XML", "JSON", "text", "md") for{ ext <- list lower = ext.toLowerCase if lower != "html"} { println("Accepted data format: " + lower) }

    产生新的集合   for(claus) yield {body} 可以用来产生新的集合。

    val result =
      for(i <- 1 to 3; j <- 2 to 4)
      yield {
        i + j
      }
    println(result)

    4.match

    "your selector" match {
      case "case 1" => //handle case 1     
      case "case 2" => //handle case 2
      ...
      case _ => //handle the rest, like default in switch-case
    }
    • 任意类型的常量或结果为常量的表达式都可以用于match语句。
    • 每个分支不需要以break结束,因为Scala里没有贯穿执行(fall through)。
    • 与if表达式一样,match表达式也有结果。这也是可以理解的,match其实是多个分支的if的另一种写法。
    def passed_?(grade: Char) = {
      grade match {
        case 'A' | 'B' | 'C' => true    //case 'A' | 'B' | 'C' => true这正是其他语言中,switch-case贯穿执行的情况
        case _ => false
      }
    }

    5.异常

    当碰到异常情况时,方法抛出一个异常,终止方法本身的执行,异常传递到其调用者,调用者可以处理该异常,也可以升级到它的调用者。运行系统会一直这样升级异常,直到有调用者能处理它。 如果一直没有处理,则终止整个程序。

    • 抛出异常:用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方。
    • //并不像Java代码那样,需要声明方法会抛出异常,这给程序员省去理论很多烦恼。
      def divide(x: Int, y: Int): Int = { if (y == 0) throw new Exception("Divide by zero") else x / y }
    • 捕捉异常:
      • 在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码里,是一系列case字句。
      • 异常捕捉的机制与其他语言中一样,如果有异常发生,catch字句是按次序捕捉的。因此,在catch字句中,越具体的异常越要靠前,越普遍的异常越靠后。 如果抛出的异常不在catch字句中,该异常则无法处理,会被升级到调用者处。 

    finally字句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,一般用于对象的清理工作。

    6.中断循环:  

    • Scala中没有break或continue关键字。可以使用Breaks类的break方法,来实现退出循环的功能。breakException是一个ControlThrowable类型的异常。此外,你的循环代码还需要用breakable包围起来,breakable的作用是捕获break抛出的异常,以免影响你真正的产品代码。
      import scala.util.control.Breaks._
    • 函数式编程的思想,尽量避免使用break。函数式编程几乎离不开递归。 更特别的,以下hasHtml是一个尾递归,大部分函数式语言编译器都对尾递归有优化,Scala也不例外。对程序员来说,不用担心使用尾递归会带来性能下降。
    val list = List("functions.md", "menu.json", "index.html", "data.xml")
    
    def hasHtml(input: List[String]): Boolean = {
      input match {
        case Nil => false
        case x :: sub => {
          if(x.endsWith("html")) return true
          else hasHtml(sub)
        }
      }
    }
    
    if(hasHtml(list)) println("There is at least one html file in the list")
    else println("There is no html file in the list")

    V.类和对象

    1.默认的访问修饰符是public。

    Scala的类都有默认的基本构造函数,可以使用new来创建对象。 

    • 在类定义中,所有不属于方法和字段的语句,都属于主构造函数。

    • 基本构造函数的参数就是类参数,类参数(或默认构造函数参数)默认的访问级别是对象私有,即private[this] val,若想要在类外部也能使用,只需显示注明为val或var,比如class ScoreCalculator(val athlete: String)

    • 私有构造函数  private放在类参数列表前
      class ScoreCalculator private(val athlete: String) 
    class ScoreCalculator(athlete: String) {
      private var total, count = 0
      
      println("This is in the primary constructor")
      
      def report(score: Int) {
        total += score
        count += 1
      }
      
      def score = if (count == 0) 0 else total / count 
      
      override def toString() = athlete + "'s score is " + score
    }
    
    val sc = new ScoreCalculator("Yao")
    println("
    Just created an object, now you can use it.
    ")
    sc.report(80)
    sc.report(90)
    println(sc)
    • 辅助构造函数 :构造函数用this标识。必须先调用主构造函数,或者在它之前定义的其他构造函数。这意味着,主构造函数是唯一创建对象的途径,不论你调用的是哪个构造函数。
    class ScoreCalculator {
      var athlete = ""
      var degreeOfDifficulty = 0.0
      
      def this(athlete: String) {
        this()       //Call primary constructor
        this.athlete = athlete
      }
      
      def this(athlete: String, degreeOfDifficulty: Double) {
        this(athlete)   //Call another auxiliary constructor
        this.degreeOfDifficulty = degreeOfDifficulty
      }
      
      override def toString = "Athlete: " + athlete + ", degree of difficulty: " + degreeOfDifficulty
    }
    
    val sc1 = new ScoreCalculator("Gao Min")
    sc1.degreeOfDifficulty = 3.7
    println(sc1)
    
    val sc2 = new ScoreCalculator("Fu Mingxia", 3.5)
    println(sc2)

    2.类的属性

    • scala的getter方法格式如name_= (parameters),名称,下划线和等号是一个整体,之间不能有空格。
    • setter方法必须与getter成对出现,也就是不能只写不读。相反,getter可以单独出现,也就是说只读是可能的。
    • 没有声明为private的字段自动生成getter,setter方法。

    不是很懂,再研究吧。

    3.单例对象:消除静态。单例对象可分为两种,不与某个类共享源文件和名称的,称为独立对象(Standalone Object),与此相反,与某个类共享名称的,称为伴生对象(Companion Object)。

    • 独立对象类似于静态类,在一个运行环境中,只会有唯一一个这个类型的对象,它是单例设计模式的天然实现,在第一次被使用的时候由运行环境将它实例化。其定义方式与类相似,只是将关键字换成object。 其他的方面也跟类相似,比如可以继承其他类和特质。只是有一个区别,不能有类参数,也就是构造函数参数。
    • 如果一个单例对象跟类有相同的名字,而且它们在同一个源文件里,那么就称之为这个类的伴生对象。它和伴生类能互相访问对方的私有成员。
    • apply方法是对象的一类特有方法,一般可用于创建伴生类。apply方法可以用简洁的方式调用,形如Object(args..)。

    4.独立对象可以包含main方法,并且可以用extends App表示(app特质)。

    object MyApplication extends App {
      args.foreach(println)
    }
  • 相关阅读:
    asp.net后台获取html控件的值
    asp.net自定义错误页面
    关于asp.net网站中web.config的配置
    在asp.net中如何使用Session
    Ubuntu 14.10 进入单用户模式
    原码,反码和补码
    利用位运算进行权限管理
    php redis扩展安装
    不同浏览器Cookie大小
    include和require的区别
  • 原文地址:https://www.cnblogs.com/aezero/p/4563489.html
Copyright © 2011-2022 走看看