您的位置:首页 > 其它

Scala基础

2015-10-27 23:08 183 查看
在Scala中,几乎所有的语言元素都是表达式。

println("hello wolrd")


是一个表达式,

"hello"+" world"


也是一个表达式。

可以通过val定义一个常量,亦可以通过var定义一个变量。推荐多使用常量。

声明 def

可以使用def来定义一个函数。函数体是一个表达式。

使用Block表达式的时候,默认最后一行的返回是返回值,无需显式指定。

函数还可以像值一样,赋值给var或val。因此函数也可以作为参数传给另一个函数。

def square(a: Int) = a * a

def squareWithBlock(a: Int) = {

a * a

}

val squareVal = (a: Int) => a * a

def addOne(f: Int => Int, arg: Int) = f(arg) + 1

println("square(2):" + square(2))

println("squareWithBlock(2):" + squareWithBlock(2))

println("squareVal(2):" + squareVal(2))

println("addOne(squareVal,2):" + addOne(squareVal, 2))


借贷模式

由于函数可以像值一样作为参数传递,所以可以方便的实现借贷模式。

这个例子是从/proc/self/stat文件中读取当前进程的pid。

withScanner封装了try-finally块,所以调用者不用再close。

注:当表达式没有返回值时,默认返回Unit。

import scala.reflect.io.File

import java.util.Scanner

def withScanner(f: File, op: Scanner => Unit) = {

val scanner = new Scanner(f.bufferedReader)

try {

op(scanner)

} finally {

scanner.close()

}

}

withScanner(File("/proc/self/stat"),

scanner => println("pid is " + scanner.next()))


按名称传递参数

这个例子演示了按名称传递参数,由于有除以0,所以运行该程序会产生异常。

val logEnable = false

def log(msg: String) =

if (logEnable) println(msg)

val MSG = "programing is running"

log(MSG + 1 / 0)


试着将

def log(msg: String)


修改为

def log(msg: => String)


由按值传递修改为按名称传递后将不会产生异常。

因为log函数的参数是按名称传递,参数会等到实际使用的时候才会计算,所以被跳过。

按名称传递参数可以减少不必要的计算和异常。

定义类

可以用class关键字来定义类。并通过new来创建类。

在定义类时可以定义字段,如firstName,lastName。这样做还可以自动生成构造函数。

可以在类中通过def定义函数。var和val定义字段。

class Persion(val firstName: String, val lastName: String) {

private var _age = 0

def age = _age

def age_=(newAge: Int) = _age = newAge

def fullName() = firstName + " " + lastName

override def toString() = fullName()

}

val obama: Persion = new Persion("Barack", "Obama")

println("Persion: " + obama)

println("firstName: " + obama.firstName)

println("lastName: " + obama.lastName)

obama.age_=(51)

println("age: " + obama.age)


函数名是任何字符如+,-,*,/。

试着将

obama.age_=(51)


简化为

obama.age = 51


这样的简化更像调用一个变量。

鸭子类型

走起来像鸭子,叫起来像鸭子,就是鸭子。

def withClose(closeAble: { def close(): Unit },

op: { def close(): Unit } => Unit) {

try {

op(closeAble)

} finally {

closeAble.close()

}

}

class Connection {

def close() = println("close Connection")

}

val conn: Connection = new Connection()

withClose(conn, conn =>

println("do something with Connection"))


这个例子中使用

{ def close(): Unit }


作为参数类型。因此任何含有close()的函数的类都可以作为参数。

不必使用继承这种不够灵活的特性。

柯里化

这个例子和上面的功能相同。不同的是使用了柯里化(Currying)技术。

def withClose(closeAble: { def close(): Unit })

(op: { def close(): Unit } => Unit) {

try {

op(closeAble)

} finally {

closeAble.close()

}

}

class Connection {

def close() = println("close Connection")

}

val conn: Connection = new Connection()

withClose(conn)(conn =>

println("do something with Connection"))


def add(x:Int, y:Int) = x + y


是普通的函数

def add(x:Int) = (y:Int) => x + y


是柯里化后的函数,相当于返回一个匿名函数表达式。

def add(x:Int)(y:Int) = x + y


是简化写法

柯里化可以让我们构造出更像原生语言提供的功能的代码

试着将例子中的withclose(…)(…)换成withclose(…){…}

范型

之前的例子可以使用泛型变得更简洁更灵活。

def withClose[A <: { def close(): Unit }, B](closeAble: A)

(f: A => B): B =

try {

f(closeAble)

} finally {

closeAble.close()

}

class Connection {

def close() = println("close Connection")

}

val conn: Connection = new Connection()

val msg = withClose(conn) { conn =>

{

println("do something with Connection")

"123456"

}

}

println(msg)


试着将

"123456"


修改为

123456


虽然msg由String类型变为Int类型,但是由于使用了泛型,代码依旧可以正常运行。

Traits

Traits就像是有函数体的Interface。使用with关键字来混入。

trait ForEachAble[A] {

def iterator: java.util.Iterator[A]

def foreach(f: A => Unit) = {

val iter = iterator

while (iter.hasNext)

f(iter.next)

}

}

trait JsonAble {

def toJson() =

scala.util.parsing.json.JSONFormat.defaultFormatter(this)

}

val list = new java.util.ArrayList[Int]() with ForEachAble[Int]

list.add(1); list.add(2)

println("For each: "); list.foreach(x => println(x))

//println("Json: " + list.toJson())


这个例子是给java.util.ArrayList添加了foreach的功能。

试着再在with ForEachAble[Int]后面加上

with JsonAble

给list添加toJson的能力
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scala