[Scala] 学习Scala 语言

[Scala] 学习Scala 语言
--------------------------------------------------------------------------
1
介绍
-----
Scala 是一种支持函数式编程风格与面向对象编程风格的静态类型语言.它基于JVM运行, 最终编译为Java字节码.因此对JAVA程序员非常易于掌握.

2
Scala VS Java
--------------
全面对象化的类型系统
Any - AnyVal (Unit, Boolean Byte Char Short Int Long Float Double)
- AnyRef (Option, Some, None, ..)


PS:
Scala 的 String 使用java.lang.String, 即支持Java类型系统.
Scala 的 Unit 相当于 Java的 void.
Scala 新增加: None, Some, Option.
至此,类型系统全面对象化.

3
简化的 for 语句

for (i <- 0 to 4) println(i) // loop 5 times(0-4)
for (i <- 0 until 4) println(i) // loop 4 times(0-3)
for (c <- "hello") print(c) // h e l l o
for (a <- List(1,2,3)) print(a) // 1 2 3


简化的 嵌套 for 语句

for(i <- 1 until 4 ; j <- 1 to 3) print(i,j)
// 1,1 1,2 1,3, 2,1 2,2 2,3 3,1, 3,2, 3,3


带条件的 for 语句

for ( a <- List(1,2,3) if a > 1) print(a)


4
函数(方法/字段)定义 def

val a:Int = 0 // 常量
var i:Int = 0 // 变量
def max(x: Int, y: Int): Int = {
if (x > y) x
else y
}

max(1, 2) // 2


4
类定义, 接口, 继承,组合

trait Drawable {
def render() = {
// ...
}
}
class Point(val x:Int,val y:Int) extends Any with Drawable{
def +(p:Point):Point = {
new Point(x + p.x,y + p.y)
}

def render() = {

}
}

case class Circle(val x:Int,val y:Int, val r:Int) extends Point(x, y) with Drawable {

override def +(r:Circle):Circle = {
Nothing
}

override def render() = {

}
}

val p1 = new Point(1, 1)
val p2 = new Point(2, 2)
val p3 = p1.+(p2)
// or like this "DSLs", 这样非常好理解.
val p4 = p1 + p2 // 只有一个参数才能这样写


case 类定义

sealed class HttpMethod {
case class Get
case class Post
case class Put
case class Head
case class Delete
}

match {
case Get =>
case Post =>
case Put =>
case Head =>
case Delete =>
case _ => None
}



PS: 注意构造参数使用的是: val; case 类不需要new,因为编译器会生成工厂方法来创建对象且会重写 hashcode, equals方法用于模式匹配.

5
val vs var vs const
val 相当于常量, var 相当于变量, const 常数.

6
pattern match
模式匹配与 match 语句


def decode(n:Int){
println(n match {
case 1 => "One"
case 2 => "Two"
case 5 => "Five"
case _ => "Error"
}
)
}

decode(1) // One
decode(3) // Error


PS: match 没有穿透问题, 避免了潜在的缺陷. 模式匹配支持字符串, case类, 常量, 集合.
_ 通配符
_* 匹配0-N个集合元素
* 匹配0-N个

7
类型推断
自动默认类型推断,同JAVA规则
val i = 3;
i 推断为 Int.

当推断有多种选择时,也可以显式指明
val i:Short = 3; // Short
val j:Int = 3; // Int

8
一切皆是对象
函数也是对象, 也可以作为参数传递, 返回值, 变量引用.

def sqrt(x:Int) = x * x
等价于
Function1(A,B)
等价于
apply(A):B

匿名函数
(x:Int) = x * x

高阶函数
def sum(f:Int=>Int, a:Int, b:Int):Int = {
if (a > b) 0
else f(a) + sum(f(a+1), a+1, b)

}

sum((x:Int) => x * x, 1, 3) // 14

曲里化
def sum(f:Int=>Int)(a:=>Int)(b:=>Int) = { // a:=>Int 命名参数,Call By Name
if (a > b) 0
else f(a) + sum(f(a+1), a+1, b)
}


(Int=>Int)=>Int=>Int=> { // Int=>Int 第一个函数调用, Int=>Int
if (a > b) 0
else f(a) + sum(f(a+1), a+1, b)
}

val lst=List(1,7,2,8,5,6,3,9,14,12,4,10) // lst 常量引用一个List对象

9
强大的泛型 [T]
编译期决定类型, 不需要强制转换.

[+T] :协变
[-T] :逆变
<: extends // <? extends T>
>: super // <? super T>

方法泛型:
override final def map[B](f : (A) => B) : List[B]

f : (A) => B
这个参数f 类型是一个偏函数, 因为有 =>
(A) : 函数参数列表

偏函数是指一个不完整的函数, 它没有函数名,甚至过参数列表也可以没有.
def f(x):Unit = println(x) // 函数
(x) => println(x) // 偏函数
def f():Unit = println(2+2) // 函数
() => println(2+2) // 偏函数
println(2+2) // 偏函数 或 叫函数字面量, 借贷模式作回调
用.
{ println(2+2) } // 偏函数 或 叫函数字面量, 借贷模式作回调

10
Tuple 元组, 可以包含混合类型元素. 使用 _index 访问(注意要带下划线,与列表不同),index 从 1 开始. List是从0开始.
(x) // 1元
(x, y) // 2元
(x, y, z) // 3元


(3, 'c')

List
List(1, 2, 3) === Tuple(1, List(2, 3)) // head 1 tail (2,3)
=== Tuple(1, 2, 3)

Map
Map("one" -> 1, "two" -> 2, "three" -> 3)
10
::
:::

List(1,2)::List(3,4) // List(List(1,2), 3, 4)
List(1,2):::List(3,4) // List(1,2, 3, 4)

11
=> pattern match

12
''' 字符串引用

13
`v` 变量

14

package cn.bisoft.scala {
const PI = 3.14
class A
class B
class C private
}

import cn.bisoft.scala._

or
import cn.bisoft.scala.{A, B}

or
import cn.bisoft.scala.PI

15
yield

val lst = List(1, 7, 13)
for {i <- lst; j <- lst if isOdd(i * j)} yield i * j
// List(1, 7, 13, 7, 49, 91, 13, 91, 169)


16
Nil 空集合
None
Null
Nothing exception

17
dock type

18
trait 接近于接口,但 trait 可以定义方法体。
scala 可以在一个class实例化的时候织入一个trait.
在scala中,实现trait用extends t1 with t2 with t3 ...

19
actor
来自 erlang 语言的概念, 很强大的东西,很多网页游戏的服务器就是用 erlang 开发的,用于支持高并发.scala 目前的标准实现为 Akka.



import scala.actors.Actor.actor
import scala.actors.Actor.receive
import scala.actors.Actor

object Main {
var count:Long = 0L
val msg1:String = "大兵: 老爷, 他鼻子是自己咬烂的!"
val msg2:String = "奇志: 我何事咬得到我自己的鼻子了!"
val msg3:String = "大兵: 他站凳子上咬烂的!"

val actorQZ:Actor = actor {
while(true) {
receive {
case s:String => {
println(s)
count += 1
actorDB ! count + msg2
}
}
}
}

val actorDB:Actor = actor {
actorQZ ! msg1

while(true) {
receive {
case s:String => {
println(s)
actorQZ ! msg3
}
}
}
}

def main(args: Array[String]) = {

}

}




package base

/**
* 分数
*/
class Rational(cN:Int, cD:Int) {
// -----------------------------------------------------------
/// constructor area
// require(cD != 0) // 先决条件,错误抛出异常

if (cD == 0) throw new IllegalArgumentException("cD must not be 0")

// 最大公约数
lazy val g:Int = gcd(cN.abs, cD.abs)

// 字段,默认私有
lazy val n:Int = cN / g // 分子
lazy val d:Int = cD / g // 分母

//子构造器
def this(cN:Int) = this(cN, 1)

// ----------------------------------------------------------
/// method area
// 重写
override def toString() = if (d.abs == 1) n + "" else n + "/" + d

def +(that:Rational) = new Rational(n * that.d + that.n * d, d * that.d)
def -(that:Rational) = new Rational(n * that.d - that.n * d, d * that.d)
def *(that:Rational) = new Rational(n * that.n, d * that.d)
def /(that:Rational) = new Rational(n * that.d, d * that.n)

// 私有方法,求最大公约数
private[this] def gcd(a:Int, b:Int):Int = if (b == 0) a else gcd(b, a % b)

}

object Rational {
/// 隐式类型转换, 必须定义在伴生对象中
implicit def intToRational(v:Int) = new Rational(v)

def main(args:Array[String]) = {
val r1 = new Rational(1, 5)
println(r1) // 1/5

val r2 = new Rational(8, 9)
println(r2) // 8/9

val r3 = r1 * 2
println(r3) // 2/5

val r4 = 2 * r2
println(r4) //16/9

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值