coderplay
12/11/2013 - 4:29 AM

scala学习

scala学习

变量

// 变量
var x = 6
// 常量
val x = 6
// 显式类型
var x:Double = 6

常用操作

  • map 遍历集合(collection)内元素, 分别应用一个函数
map - transform each item in the collection   
val doubleIt = range2.map(_ * 2)  
println(doubleIt) //Vector(2, 4, 6, 8, 10, 12, 14, 16, 18) 
val doubleIt = range2.map(_ * 2)  
println(doubleIt) //Vector(2, 4, 6, 8, 10, 12, 14, 16, 18) 
  • filter 对集合(collection)内元素进行条件过滤
//filter - keep only items larger than 4   
val moreThan4 = range.filter(_ > 4)  
println(moreThan4) //Vector(5, 6, 7, 8, 9, 10)

函数

// 定义函数 
def add(x:Int, y:Int):Int = {  
  return x + y   
}  
println(add(42,13))  
// return 关键字可有可无
def add(x:Int, y:Int) = { //result type is inferred   
  x + y //"return" keyword is optional  
}  
println(add(42,13))   
// Curly braces are optional on single line blocks  
def add(x:Int, y:Int) = x + y  
println(add(42,13))  
  • 匿名函数 函数是一等公民, 可以传一个匿名函数作为另一函数的参数
//a method that requires a function as a parameter  
//the function's type is (Int,Int) => Int  
//e.g. maps from 2 Ints to an Int  
def doWithOneAndTwo(f: (Int, Int) => Int) = {  
  f(1, 2)  
}  

//Explicit type declaration  
val call1 = doWithOneAndTwo((x: Int, y: Int) => x + y)  

//The compiler expects 2 ints so x and y types are inferred  
val call2 = doWithOneAndTwo((x, y) => x + y)  

//Even more concise syntax  
val call3 = doWithOneAndTwo(_ + _)  

println(call1, call2, call3)  

模式匹配

面向对象

this 别名

this 别名对于一个内部类需要访问外部类的this时候有用

class Outer { outer =>
  class Inner {
    println(Outer.this eq outer) // prints: true
  }
}

sealed class

经常用于match. sealed class除非同文件里定义的子类, 否则不能继承自此类. 这有利于限定match case 的范围. 不至于别人随便继承的class, 在你的case 语句里没有match到.

ealed abstract class Expr
case class Var(name: String) extends Expr
case class Number(num: Double) extends Expr
case class UnOp(operator: String, arg: Expr) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr

def describe(e: Expr): String = e match {
  case Number(_) => "a number"
  case Var(_)    => "a variable"
}

lazy field

lazy field只有在用到它的时候才赋值

object apply 函数

Mathematicians have their own little funny ways, so instead of saying then we call function f passing it x as a parameter as we programmers would say, they talk about applying function f to its argument x.

In mathematics and computer science, Apply is a function that applies functions to arguments.

Wikipedia

apply serves the purpose of closing the gap between Object-Oriented and Functional paradigms in Scala. Every function in Scala can be represented as an object. Every function also has an OO type: for instance, a function that takes an Int parameter and returns an Int will have OO type of Function1[Int,Int].

 // define a function in scala
 (x:Int) => x + 1

 // assign an object representing the function to a variable
 val f = (x:Int) => x + 1

Since everything is an object in Scala f can now be treated as a reference to Function1[Int,Int] object. For example, we can call toString method inherited from Any, that would have been impossible for a pure function, because functions don't have methods:

f.toString Or we could define another Function1[Int,Int] object by calling compose method on f and chaining two different functions together:

val f2 = f.compose((x:Int) => x - 1) Now if we want to actually execute the function, or as mathematician say "apply a function to its arguments" we would call the apply method on the Function1[Int,Int] object:

f2.apply(2) Writing f.apply(args) every time you want to execute a function represented as an object is the Object-Oriented way, but would add a lot of clutter to the code without adding much additional information and it would be nice to be able to use more standard notation, such as f(args). That's where Scala compiler steps in and whenever we have a reference f to a function object and write f (args) to apply arguments to the represented function the compiler silently expands f (args) to the object method call f.apply (args).

Every function in Scala can be treated as an object and it works the other way too - every object can be treated as a function, provided it has the apply method. Such objects can be used in the function notation:

// we will be able to use this object as a function, as well as an object object Foo { var y = 5 def apply (x: Int) = x + y }

Foo (1) // using Foo object in function notation There are many usage cases when we would want to treat an object as a function. The most common scenario is a factory pattern. Instead of adding clutter to the code using a factory method we can apply object to a set of arguments to create a new instance of an associated class:

List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation

// the way the factory method invocation would have looked // in other languages with OO notation - needless clutter List.instanceOf(1,2,3) So apply method is just a handy way of closing the gap between functions and objects in Scala.

隐式转换和隐式参数

隐式转换

隐式转换常用在这种情况: 软件的两部分独立地开发, 都不知道对方的接口. 隐式转换可以很好地让这两部分协作起来, 而且避免了从一种类型转换成另一种类型的显示转换.