Scala(10)scala的泛型、视图界定、上下界界定、上下文界定、柯里化实现隐式转换

**
 * [T <: Comparable[T]] 上界  upper bound     java: <T extends Comparable>
 * [T >: Comparable[T]] 下界  lower bound     java: <T super Comparable>
 * [T <% Comparable] 视图界定   view bound
 * [T : Comparable] 上下文界定 context bound
 * [-T] 逆变   方法输入参数
 * [+T] 协变   方法返回
 *
 */

class Pair[T <: Comparable[T]] {

  def bigger(first: T, second: T): T = {
    if(first.compareTo(second) > 0) first else second
  }

}

object Pair {

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

   //val p = new Pair[String]

    //val r = p.bigger("hadoop", "spark")

    //val p1 = new Pair[Integer]
    //将上界改成视图界定,Scala的Int也可以比较了(隐式转换)
    val p1 = new Pair[Int]
    //scala中的Int没有实现Comparable接口,所以没法执行
    //java中的Integer有实现Comparable接口,可以比
    val r = p1.bigger(10, 8)

    println(r)

  }




}

自定义类型实现比较

使用上界实现隐式转换:

class Girl(val name: String, var age: Int) extends Ordered[Girl]{

  override def compare(that: Girl): Int = {

    this.age - that.age

  }

  override def toString = s"Girl($name, $age)"
}
class MissRight[T <: Ordered[T]] {

  def choose(first: T, second: T): T = {
    if(first > second) first else second
  }

}

object MissRight {

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

    val missRight = new MissRight[Girl]
    val g1 = new Girl("aaa", 18)
    val g2 = new Girl("bbb", 19)
    val g = missRight.choose(g1, g2)
    println(g)

  }

}

使用视图界定实现隐式转换:

//视图界定:会有一个隐式转换将T转换成Ordered[T]
//视图界定需要一个隐式转换方法或隐式转换函数
class Pair2[T <% Ordered[T]] {

def select(first: T, second: T): T = {
if(first > second) first else second
}

}

object Pair2 {

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

import MyContext.girlToOrderedGirl

val p = new Pair2[Girl2]

val g1 = new Girl2("ab", 88.98)
val g2 = new Girl2("hatna", 99.99)

val g = p.select(g1, g2)

println(g)

}

}

//不把比较规则写到这个类中,但是还是要具备比较的功能
class Girl2(val name: String, var fv: Double) {

override def toString = s"Girl2($name, $fv)"
}

import java.io.File

object MyContext {

  implicit val aaa = 111

  implicit val bbb = 111.111


  //如果既有相同功能的隐式转换方法和函数,优先调用隐式转换函数
  implicit def fileToRichFile(file: File): RichFile = {
    println("method invoked")
    new RichFile(file)
  }

  implicit val file2RichFIle = (file: File) => {
    println("function invoked")
    new RichFile(file)
  }

  implicit def girlToOrderedGirl(girl: Girl2): Ordered[Girl2] = new Ordered[Girl2] {

    override def compare(that: Girl2): Int = {
      //升序
      (girl.fv - that.fv).toInt

    }
  }

  implicit val g2OreredGirl = (girl: Girl2) => new Ordered[Girl2] {
    override def compare(that: Girl2): Int = {

      println("function invoked")
      //降序
      (that.fv - girl.fv).toInt

    }
  }

  //隐式参数
  implicit object OrderingBoy extends Ordering[Boy] {
    override def compare(x: Boy, y: Boy): Int = {

      (x.fv - y.fv).toInt

    }
  }

}

视图界定和上界界定就是来实现隐式转换的:

上下文界定:

class Boy(val name: String, var fv: Double) {

  override def toString = s"Boy($name, $fv)"
}
//上下文界定,也是实现隐射转换的
//上下文界定需要一个隐式转换参数
class Pair3[T : Ordering] {

  def choose(first: T, second: T): T = {
    val ord: Ordering[T] = implicitly[Ordering[T]]
    if(ord.gt(first, second)) first else second
  }

}

object Pair3{

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

    import MyContext.OrderingBoy

    val p = new Pair3[Boy]

    val b1 = new Boy("laoduan", 99.99)
    val b2 = new Boy("xiaozhao", 9999.99)

    val b = p.choose(b1, b2)

    println(b)

  }

}

使用柯里化实现隐式转换:
//即不用视图界定,又不用上下文界定,但是要实现隐射转换
//结合柯里化实现
class Pair4[T] {

//使用柯里化方法接口隐式函数或隐式方法,可以实现类似视图界定的功能
def select(first: T, second: T)(implicit f: T => Ordered[T]): T = {
if (first > second) first else second
}

//使用柯里化方法接口隐式参数,可以实现类似上下文界定的功能
def choose(first: T, second: T)(implicit ord: Ordering[T]): T = {
if(ord.gt(first, second)) first else second
}

}

object Pair4 {

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

val arr = Array[Int](1,2,3,9,8,7,5)
// Int 到 Ordering[Int] 的隐式转换参数
arr.sorted
//arr.sortBy()


val p = new Pair4[Boy]

import MyContext.OrderingBoy

// implicit val f = (g: Girl2) => new Ordered[Girl2]{
// override def compare(that: Girl2): Int = {
//
// println(“function invoked”)
// //降序
// (that.fv - g.fv).toInt
//
// }
// }
val g1 = new Boy(“ab”, 88.98)
val g2 = new Boy(“hatna”, 99.99)

//val g = p.select(g1, g2)

val g = p.choose(g1, g2)

println(g)

}

}

隐式转换总结:

什么是隐式转换:在Scala中,可以对方法进行增强或扩展方法的功能叫做隐射转换,本质就是装饰模式

有哪些语法可以实现隐式转换呢?
视图界定:需要隐式转换函数或隐式方法
上下文界定:需要隐式转换参数
柯里化,有两种方式,一种是传入隐式转换方法,另外一种隐式转换参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值