scala备忘(二)
2017-02-06 本文已影响0人
tjuhenryli
一、泛型类
class Pair1[T,S](val first:T , val seconds:S) {
override def toString():String = first + "," + seconds
def getMiddle[T](a:Array[T]):T = a(a.length/2)
}
二、上界 <: (T为Comparable的子类型)
class Pair2[T <: Comparable[T]](val first:T,val second:T) {
def smaller:T = if (first.compareTo(second)<=0) first else second
}
三、下界 >:(R是T的父类)
class Pair3[T](val first:T,val second:T) {
def replaceFirst[R >: T](newFirst:R) = new Pair3(newFirst,second)
override def toString():String = first + "," + second
}
四、视图界定 <% T能够隐式转换成Ordered[T]
class Pair4[T <% Ordered[T]](val first:T,val second:T) {
def smaller:T = if (first <= second) first else second
}
五、上下文界定 T:M[T] 存在一个M[T]的隐式值
class Pair5[T:Ordering](val first:T,val second:T) {
def smaller(implicit ord:Ordering[T]) = if (ord.compare(first,second)<0) first else second
}
六、逆变、协变
/**
* 协变(+T): Student是Person的子类型,那么Pair6[Student]也是Pair6[Person]的子类型
* 逆变(-T): Student是Person的子类型,那么Pair7[Student]就是Pair7[Person]的父类型
*/
class Pair6[+T](first:T,second:T)
class Link[+T](val head:T,val tail:Link[T])
//逆变
class Pair7[-T](first:T, second:T)
class Animal{}
class Bird extends Animal{}
class Consumer[T](t: T){
// def get(): T = t
def use(t:T) = {}
}
class Consumer1[+T](t: T){
/**
* 方法的返回值是协变的位置,方法的参数是逆变的位置
* covariant(协变) type T occurs in contravariant(逆变) position in type T of value t
* covariant(协变) type T occurs in contravariant position in type <: T of type U
*/
def get(): T = t
// def use(t:T) = {}
def use[U>:T](t:U) = {}
}
class Consumer2[-T](t: T){
// def get[U<:T](): U = U
// def use(t:T) = {}
}
class Consumer3[-S,+T]() {
// def m1[U >: T](u: U): T = {new T} //协变,下界
// def m2[U <: S](s: S): U = {new U} //逆变,上界
}
七、类型约束
/**
* 类型约束
* T=:=U(T是否=U),T<:<U(T是否为U的子类型),T<%<U(T是否隐式转换为U)
* 在特定条件下(具体方法) 进行类型检测
* Pair[File] 可以构造出,但是使用smaller方法的时候,就会报错.
*/
class Pair8[T](val first:T,val second:T) {
def smaller(implicit ev:T <:<Ordered[T]) = if (first<second) first else second
}
八、定义类和伴生对象
/**
* 主构造器在类名后,参数会被声明字段,若参数没有使用var或者val声明,则会被声明称私有字段
*/
case class Person(val id:String, var name:String,val age:Int){
private val date = "2016-10-20"
// private[this] val: Int = .. ????
override def toString = id+","+name+","+age+","+date
}
object Person{
/* 隐式对象
* 执行过程检查当前作用是否有 implicit object 限定的 类型为 Ordering 的对象,如有,则选取此对象
*/
implicit object PersonOrdering extends Ordering[Person] {
override def compare(x: Person, y: Person) = (x.id==y.id) match {
case false => x.id.compareTo(y.id)
case _ => x.name.compareTo(y.name)
}
}
/* 隐式类
* 当 1.add(2) 时,scala 编译器不会立马报错,而检查当前作用域有没有 用implicit 修饰的,
* 同时可以将Int作为参数的构造器,并且具有方法add的类,经过查找 发现 Calculate 符合要求
*/
implicit class Calculate(x:Int) {
def add(second:Int) = x + second
}
}
九、私有字段(快学scala)
class Counter {
private var value = 0 //在其他地方不能访问;
private[this] var my = 0 //
def increment = value += 1
def increment(n:Int) = my += n
//能在Counter类方法中 访问Counter对象的私有字段
def isLess(other:Counter) = value<other.value
// def isMore(other:Counter) = my<other.my //errors
}
十、封闭类
/**
*
* 定义类型为sealed(封闭类)允许编译器进行彻底的分析(这是针对模式匹配的,参考Programming in Scala)
* 因为构造器将不能从外部源文件中添加
*/
sealed trait Tree[T]
case class Node[T](left: Tree[T], right: Tree[T]) extends Tree[T]
case class Leaf[T](value: T) extends Tree[T]
十一、模式匹配
def findMin[T <: Ordered[T]](tree: Tree[T]):T = tree match {
case Node(left, right) => Seq(findMin(left), findMin(right)).min
case Leaf(value) => value
}
def suffix(i: Int) = i match {
case 1 => "st"
case 2 => "nd"
case 3 => "rd"
case _ => "th"
}
var opt: Option[String] = None
opt = Some("foobar")
opt match {
case Some(value) => // operate(value)
case None => // defaultAction()
}
//使用模式匹配实现类型转换
obj match {
case str: String => ...
case addr: SocketAddress => ...
}
//模式匹配在和解构(destructuring)联合使用时效果最好
animal match {
case Dog(breed) => "dog (%s)".format(breed)
case other => other.species
}
//14.1 better than switch
var ch = '9'
var sign = ch match {
case '+' => 1
case '-' => -1
case _ => 0
}
// 14.2 boolean condition
var digit = 0
ch match {
case '+' => sign = 1
case '-' => sign = -1
case _ if Character.isDigit(ch) => digit = Character.digit(ch, 10)
case _ => sign = 0
}
val obj:Any = BigInt(100)
val result = obj match {
case x:Int => x
case s:String => Integer.parseInt(s)
case _:BigInt => Int.MaxValue
case _ => 0
}
val arr = Array(0,1)
val arr_result = arr match {
case Array(0) => "0"
case Array(x,y) => x+" "+y
case Array(0,_*) => 0 + " ..."
}