zoukankan      html  css  js  c++  java
  • scala的一些特殊用法

    1.创建多行字符串,只要把多行字符串放在3个双引号间("""...""")即可。这是Scala对于here document,或者叫heredoc的支持。这里我们创建一个三行长的字符串:

    MultiLine.scala

    val str = """Hello world!
    How are you!
    Good morning!"""
    println(str)

    输出如下:

    Hello world!
    How are you!
    Good morning!
    请按任意键继续. . .

    2.运算符优先级

    Scala没有定义运算符的优先级,但它定义了方法的优先级。

    方法名的第一个字符决定了它的优先级。如果表达式里面有两个具有相同优先级的字符,那么左边的运算符优先级更高。下面从低到高列出了首字符的优先级:

    所有字母
    |
    ^
    &
    < >
    = !
    :
    + -
    * / %
    所有其他特殊字符

    举例如下:

    Complex.scala

    class Complex(val real:Int, val imag:Int) {
        def +(operand:Complex):Complex={
          println("Calling +")
          new Complex(real+operand.real , imag+operand.imag)
        }
        
        def *(operand:Complex):Complex={
          println("Calling *")
          new Complex(real*operand.real - imag*operand.imag , real*operand.imag + imag*operand.real )
        }
        override def toString():String = {
          real + (if(imag<0) ""else "+")+ imag + "i"
        }
    }
    
    object Complex extends App {
      val c1 = new Complex(1,4)
      val c2 = new Complex(2,-3)
      val c3 = new Complex(2,2)
    //  val sum = c1 + c2
    //  println("(" + c1 + ") + (" + c2 + ")=" + sum )
      println(c1+c2*c3)
    }

    运行结果如下:

    Calling *
    Calling +
    11+2i

     3. 类继承

    在scala里,继承一个基类跟Java的做法很相似,只是多了两点限制:

    (1)重写方法需要override关键字

    (2)只有主构造函数才能往基类构造函数中传参数

    下面是继承一个基类的例子:

    Vehicle.scala

    class Vehicle(val id:Int, val year:Int) {
        override def toString(): String = "ID:" + id + " Year:" + year
    }
    
    class Cars(override val id:Int, override val year:Int, 
        var fuelLevel:Int)extends Vehicle(id,year){
      override def toString(): String = super.toString()+ " Fuel Level:" + fuelLevel
    }
    
    object Cars extends App {
      val car = new Cars(1, 2010, 100)
      println(car)
    }

    程序运行结果如下:

    ID:1 Year:2010 Fuel Level:100

    4. Scala中的static

    Scala中没有静态字段和静态方法。静态字段和静态方法会打破Scala所支持的完整的面向对象模型。不过,scala也是完全支持类一级的属性和操作的。这就是伴生对象的作用。

    举例如下:

    Marker.scala

    class Marker private(val color:String) {
        override def toString():String = "marker color "+color
    }
    
    object Marker extends App{
      private val markers = Map(
          "red" -> new Marker("red"),
          "blue" -> new Marker("blue"),
          "green" -> new Marker("green")
          )
          
      def primaryColors = "red, green, blue"
        
      def apply(color:String) = if(markers.contains(color))
        markers(color) else null
        
      println("Primary colors are:" + Marker.primaryColors)
      println(Marker("blue"))
      println(Marker("red"))
    }

    程序运行结果如下:

    Primary colors are:red, green, blue
    marker color blue
    marker color red

     5. Option类型

    Scala想让意图更清晰的表达出来,确实有时候我们就需要没有结果。Scala以一种类型安全的方式做到这一点:它使用Option[T]类型。举例如下:

    OptionExample.scala

    object OptionExample extends App{
        def commentOnPractice(input:String) = {
          //rather than returning null
          if(input == "test") Some("good") else None
        }
        for(input <- Set("test","hack")){
          val comment = commentOnPractice(input)
          println("input "+input+"comment "+comment.getOrElse("Found no comments"))
        }
    }

    程序运行结果如下:

    input testcomment good
    input hackcomment Found no comments

    将类型显式声明为Option[String],Scala会强制我们检查实例的不存在。如此一来,就不太可能因为没有检查null引用而抛出NullPointerException。调用返回Option[T]的getOrElse()方法,可以主动的应对结果不存在(None)的情形。

     6.方法返回类型推演

    除了推演变量的类型,Scala也会尝试推演方法返回值的类型。不过,这有个陷阱,推演会依赖于方法如何定义。如果用等号(=)定义方法,Scala就可以推演返回类型。否则,它就假设方法是一个void方法。

    7. 隐式类型转换

    举例如下:

    import java.util._
    class DateHelper(number:Int) {
        def days(when:String):Date = {
          var date = Calendar.getInstance()
          when match {
            case DateHelper.ago => date.add(Calendar.DAY_OF_MONTH, -number)
            case DateHelper.from_now => date.add(Calendar.DAY_OF_MONTH, number)
            case _ => date
          }
          date.getTime();
        }
    }
    
    object DateHelper extends App{
        val ago = "ago"
        val from_now = "from_now"
        implicit def convertInt2DateHelper(number:Int) = new DateHelper(number)
        val past = 2 days ago
        val appointment = 5 days from_now
        println(past)
        println(appointment)
    }

    程序运行结果如下:

    Fri Mar 13 16:49:06 CST 2015
    Fri Mar 20 16:49:06 CST 2015

     7. 使用Set,合并Set集

    如果需要将两个Set合并成一个新的Set,可以用++():

    scala> val feeds1 = Set("blog.toolshed.com","pragdave.pragprog.com","pragmactic-
    osxer.blogspot.com","vita-contemplativa.blogspot.com")
    feeds1: scala.collection.immutable.Set[String] = Set(blog.toolshed.com, pragdave
    .pragprog.com, pragmactic-osxer.blogspot.com, vita-contemplativa.blogspot.com)
    
    scala> val feeds2 = Set("blog.toolshed.com","martinfowler.com/bliki")
    feeds2: scala.collection.immutable.Set[String] = Set(blog.toolshed.com, martinfo
    wler.com/bliki)
    
    scala> val mergedFeeds = feeds1 ++ feeds2
    mergedFeeds: scala.collection.immutable.Set[String] = Set(pragdave.pragprog.com,
     pragmactic-osxer.blogspot.com, vita-contemplativa.blogspot.com, blog.toolshed.c
    om, martinfowler.com/bliki)
    
    scala> println("# of merged feeds:" + mergedFeeds.size)
    # of merged feeds:5

    Set至多持有每个元素一次,从输出里可以看到这一点,在合并后的Set里,两个Set里公共的元素只存储一次:

    如果想在每个元素前面加上“http://",可以用map()方法:

    scala> val urls = feeds1 map("http://"+_)
    urls: scala.collection.immutable.Set[String] = Set(http://blog.toolshed.com, http://pragdave.pragprog.com, http://pragmactic-osxer.blogspot.com, http://vita-con
    templativa.blogspot.com)

    如果准备对Set集进行迭代,一次一个的进行刷新,可以用内建的迭代器foreach(),像这样:

    scala> feeds1 foreach{ feed => println(" Refreshing " + feed)}
     Refreshing blog.toolshed.com
     Refreshing pragdave.pragprog.com
     Refreshing pragmactic-osxer.blogspot.com
     Refreshing vita-contemplativa.blogspot.com

     8. 用Scala实现集合中相邻元素间的差值

    如何计算同一集合中元素两两之间的差值,即求集合(a,b,c,d)中的(b-a,c-b,d-c)

    实现方法如下:

    scala> val l1 = 1 to 10 toList
    warning: there were 1 feature warning(s); re-run with -feature for details
    l1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> val l2 = l1.tail
    l2: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    scala> l1.zip(l2).map(p=>(p._2-p._1))
    res1: List[Int] = List(1, 1, 1, 1, 1, 1, 1, 1, 1)

    代码含义解释如下:

    1. tail表示一个集合中除首元素外的剩余元素,也是一个集合。
    2. zip将两个集合组成一个数值对集合,比如原来有两个集合分别是(a,b,c,d), (1,2,3,4),使用zip之后,形成((a,1),(b,2),(c,3),(d,4)),如果两个集合长度不一致,多余元素将被舍去。
    3. map操作中的p._1和p._2表示tuple(元组)中的第一个元素和第二个元素
    • head和tail  head表示头元素,tail表示除head之外的剩余元素集合
    • init和last    last表示尾元素, init表示除尾元素之外的剩余元素集合
  • 相关阅读:
    wzplayer for android V1.5 整合硬解码(仍然支持加密音视频)
    mac osx 快捷键
    从零开始学AS3游戏开发【七】永无终结,不断完善的游戏
    flash flex as3 类库 资料大全
    php include一个有全局变量的应注意
    MySQL事件调度器 CREATE EVENT
    The Miner – 专业Flash AS3性能分析器(profiler)入门教程
    as3加密入门1使用alchemy进行代码混淆
    从零开始学AS3游戏开发【五】 告别方块,添加碰撞
    PHP实现的Mysql读写分离
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4325920.html
Copyright © 2011-2022 走看看