scala入门

有必要把scala的入门记录下来。 

http://www.cnblogs.com/nod0620/articles/2236312.html

scala几要素:

1.immutable,scala可以创建immutable的对象,这样在并发编程中,可以不需要使用同步,可以不适用互斥。

2.FP,可以提高代码的简洁度和提高编码的效率,有时候编码也更加简单。

3.基于JVM,编译成Bytecode,可以和java相互作用。

4.基于事件的并发模型

5.静态强类型语言,使用类型推断使得代码非常的简洁。

 

scala 语法与一些概念

1.

val  a ="hello world"  //不需要指定类型,scala可以进行类型推断

var b =2

b =3  //val为immutable对象,var为mutable对象,优先使用val

2.

复制代码
/ **
  *scala其实没有运算符重载,因为从来都没有运算符
  *只是方法可以定义成运算符的模样
  *
**/
class Operators(val a: Int) {
  def +(other: Operators): Int = {
    this.a + other.a
  }
}
object Operators {
  def main(args: Array[String]) {
    val one = new Operators(1)
    val two = new Operators(1)
    one + two
  }
}
复制代码

3.

复制代码
// 构造器分主构造器和辅助构造器
class Operators(var a: Int) {
  var b: Int = _

  
  //辅助构造器的第一句调用必须是调用其他构造器
  //编译器会给a生成一个get方法:a(),其实也会生成set方法
  def this(a: Int, b: Int) {
    this(a)
    this.b = b
  }
  def +(other: Operators): Int = {
    this.a + other.a
  }
}
复制代码

4.

复制代码
class Singleton {

}

//object Singleton是class Singleton的伴生对象,不能有辅助构造器,主构造器也不能有参数
object Singleton {
  def staticmethod ={
    
  }
}
object Test{
  //可以直接调用 认为是java中的static
  Singleton staticmethod
}
复制代码

5.

复制代码
class Protected {
  
  private def privateMethd{}
  
  protected def protectedMethd{ privateMethd}
  
  /**
   * private[this] 只有当前实例能访问,其它类和实例不能访问
   */
  private[example] def  accessMethd{}

}

class Sub extends Protected{
    //def start1{privateMethd}  error  因为private的原因
    //默认是public的
    def start2{protectedMethd} //ok protected对于子类可见
  
    //ok
    def start3(sub:Sub){
      sub.protectedMethd
    }
    
    /**
     
    def start3(pro:Protected){
      pro.protectedMethd //error  在子类中,传入的父类参数是不能调用自己的protected方法的
    }
    
    */
}

class Other {
 // def start{protectedMethd} error  protected只对于子类可见 对于package的类不可见
  def start2(pro:Protected){pro.accessMethd} //ok 使用了[AccessQualifier] 指定包或者类是可见的
}

class Outer{
  def start(inner:Inner){inner start}
  
  class Inner{
   private[Outer] def start(){} //使用[AccessQualifier]指定类时,必须是包围类(类似java的内部类)
  }
}
复制代码

6.

复制代码
  /**
   * Tuples和多返回值  java里需要使用类实例返回
   *
   * 函数定义一般是这样:
   *
   * def  methodName(paramName:paramType):(returnType)={code body}
   *
   * paramName:paramType可以是多个的;returnType可以多个,也可以省略掉(类型推断会推断出来);=代表函数有返回值?
   *
   *
   * 此函数返回一个Tuples
   */

  def getPersonInfo(index: Int) = {
    ("firstName", "secondName", "address")

  }
复制代码



自适应类型和类型推断

先看scala和java的定义int变量的比较:

    //java
    int i = 0;
    
    //scala
    var i =0

java里面必须之类变量的类型,而scala中是可以推断出来-->类型推断,编译器进行类型检查,在不能进行类型推断的时候必须指明类型。

scala的类型层次:

 



  Any是所有的父类型,Noting是所有类型的子类型。

  Any是一个抽象类,AnyRef可以对应是java的Object类,AnyVal可以对应java的Int,Double等

  Noting是抽象的,是类型推断的帮手,当方法是抛出异常或者返回一个类型犹豫不绝的时候,Noting是可以上场的,Noting可以代表任何东西,甚至是异常.

  Option [T] 类型: 为了表达清楚一个方法返回null的情形和可以对null进行具体的检查,定义了Option[T]类型,这个是个抽象类,他的子类型Some[T]和None

  代表了返回具体的类型和没有返回(返回空类型):

复制代码
final case class Some[+A](x: A) extends Option[A] {
  def isEmpty = false
  def get = x
}


case object None extends Option[Nothing] {
  def isEmpty = true
  def get = throw new NoSuchElementException("None.get")
}
复制代码

scala容器的类型推断:

复制代码
    var list1 = new ArrayList[Int]
    var list2 = new ArrayList
    list2 = list1 // Compilation Error


    var list3 = new ArrayList[Any]
    list3 = list1 // Compilation Error
复制代码

  这个和java中容器的操作有很大的不同,在默认的情况下,scala不允许将一个持有任意类型的容器赋给另外一个持有其他类型的容器。在实施了协变以后才可以进行。

 

function value和闭包

高阶函数是指以函数为参数的函数,能减少重复代码,把不变的代码形成高阶函数,把变动的地方以函数为参数的形式传入,类似于策略模式。

function value:把函数赋值给变量或者当做参数传给其他函数,scala在内部把函数值实现为特殊类的实例,所以函数值也是对象

 

curry:可以把函数从多个参数转化成多个参数列表:

复制代码
  def before(a: Int, b: Int, c: Int, d: Int) {  //     ||
                                                  //   ||
  }                                                //  ||
                                                  //   ||
  def middle(a: Int)(b: Int, c: Int, d: Int) {    //   ||
                                                  //  curry
  }                                                //  ||
                                                  //   ||
  def after(a: Int)(b: Int)(c: Int)(d: Int) {    //    ||
                                                  //   \/ 
  }
复制代码


curry化的函数可以有一个或者多个参数未绑定,也就是形成偏应用函数,如:

复制代码
    var foo =after _
    var bar =after(1)_

  // 输出如下:

  // foo: Int => Int => Int => Int => Unit = <function1>
  // bar: Int => Int => Int => Unit = <function1>
复制代码

这样做的好处是,形成偏应用函数,当前面几个参数是固定的,后面几个参数是动态变化的,这种写法能去除前面固定参数重复定义,使代码非常简洁:

    //避免第一个参数的重复定义
    var bar =after(1)_
    bar(1)(3)(4)
    //可以使用{}调用
    bar(2)(3){5}

Lamda表达式:

scala里面的lamda表达式非常的简单:

operation:(args*) => done 

lamda是否可以简单的理解成是匿名函数?

 

闭包:

复制代码
def loopThrough(number: Int)(closure: Int => Unit) {
    for (i <- 1 to number) { closure(i) }
}

  var result = 0
  val addIt = { value:Int => result += value }

loopThrough(10) { addIt }
println("Total of values from 1 to 10 is " + result)

loopThrough(5) { addIt }
println("Total of values from 1 to 5 is " + result)
//结果是55,75 说明作用域外的赋值影响了result
复制代码



 

 

分类: scala
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值