Scala第二章学习笔记

最基本的练习~:

 

使用伴生对象:

object holder{
class Foo{ private var x = 5}
object Foo{def im_in_yr_foo(f: Foo) = f.x}
}

import holder.Foo

val x = new Foo
Foo.im_in_yr_foo(x)

 

基本的会话: Scala的if块是个表达式。在Java中,达到类似的目的就是这种代码: String x = true ? "true string" : "false string"  Scala中没有?:的语法

if(true) 5 else "hello"
if(false) 5 else "hello"

 

方法和模式匹配

在JAVA编程时,有个常用的实践是每个方法只有一个返回点。每个方法的最后一行都会是个retrun语句。 

def createErrorMessage(errorCode : Int):String = {
    var result : String = _
    errorCode match {
    case 1 =>
      result = "Network Failure"
    case 2 =>
      result = "..."
    case 3 m=>
      result = "..."
    }  
    return result;
}

使用模式匹配提供的面向表达式语法改进代码: (result改为了 val类型,模式匹配能够判断唯一的值和类型)

def createErrorMessage(errorCode : Int):String = {
    val result = errorCode matchj{
        case 1 => "NewWork Failure"
        case 2 =>"..."
        case 3 =>"..."
    }
    return result
}

最终改进结果  模式匹配是这个方法唯一一个语句,而它返回个字符串类型的表达式- -

def createErrorMessage(errorCode : Int) : String = errorCode match{ 
    case 1 => "NewWork Failuer:
    case 2 = > "....."
    case _ = >"....."
}

 

并发:

创建个索引服务,用键值来查找特定项。服务由两个方法构成,lookUp方法根据key的索引查找值,insert方法插入新值, 基本是个键值对的映射。用加锁和可变hashMap实现,第一个currentIndex指向存放数据的可变HashMap,look和insert方法都用sychronized块包起来,表明对MutableService自身做同步。

import collection.mutable.{HashMap=>MutableHashMap}
class MutableService[Key, Value] extends Service[Key, Value]{
    val currentIndex = new MutableHashMap[Key,Value]
    def lookUp(k:key) : Option[Value] = synchronized(currentIndex.get(k))
    def insert(k : key, v : value) : Unit = synchronized{
        currentIndex.put(k,v)
    }   
}

  把currentIndex改成一个不可变的HashMap,每次调用insert方法的时候覆盖原值。lookUp方法就可以不加任和锁了。currentIndex是个指向不变变量的可变引用,每次insert操作都会更新引用。

class ImmutableService[Key, Value] extends Service[Key,Value]{
    var currentIndex = new ImmutableHashMap[Key,value]
    def lookUp(k : Key) : Option[Value] = currentIndex.get(k)
    def insert(k : key, v : Value) : Unit = synchronized{
        currentIndex = currentIndex + ((k,v))
    }
}

 

 

Scala标准库提供了scala.Option类,鼓励大家在编程时尽量不要使用null.

 

Option高级技巧  (被当做集合对待)

1、创建对象或返回默认值  接收Option[String]的参数 返回指向file对象,对opiton应用map方法,在参数有值得请客下创建一个File对象。filter方法确保这个新建文件对象必须是目录。

def getTemporaryDirectory(tmpArg : Option[String] : java.io.File = {  tmpArg.map( name => new java.io.File(name)).
    filter(_.isDirectory).
    getOrElse(new java.io.File(
        System.getProperty("java.io.tmpdir")))
}

 

2、foreach方法 能够仅当Option有值时才执行某段代码块。因为Option要么有零或一个值,所以代码要么执行,要么不执行。

val username : Option[String] = ...
for(uname <- username) {
    println("User: " + uname)
)

例如:Java Servlet框架对用户进行验证,如果验证成功,则安全注入HttpSession,后续的filter和servlet可以检查用户的访问权限。 Scala的惯例是不要把null或未初始化的参数传给函数。

如果多个Option都有值则执行代码

def authenticateSession(session : HttpSession, username :Option[String],password : Option[Array[Char]]) = {
    for(u <- usrname ;p <- password;
    if canAuthenticate(usrname,password)){
        val privileges = privilegesFor(u)
        injectProvilegesIntoSession(session,privileges)
    }
}

 3、用多个可能未初始化的变量构造另一个变量 这里简单地把数据库配置参数转化为一个Option。

def createConnection(conn_url : Option[String],conn_user : Option[String],conn_pw : Option[String]) : Option[Connection] = 
    for{
            url <- conn_url
            user <- conn_user
            pw <- conn_pw
          }yield DriverManager.getConnection(url,user,pw)

上述代码可以通过转换函数,抽象化。

def lift3[A,B,C,D](f : Function3[A,B,C,D]) : Function3[Option[A], Option[B] (oa : Option[A], ob: Option[B], oc: Option[C]) =>
    for(a <- oa; b<- ob; c<- oc) yield f(a,b,c)
        }
lift3(DriverManager.getConnection)

 

posted on 2015-11-02 14:03  松伯  阅读(204)  评论(0编辑  收藏  举报