scala-柯里化、隐式转换、泛型、upperbound、viewbound、contextBound

简介: scala-柯里化、隐式转换、泛型、upperbound、viewbound、contextBound

scala-柯里化、隐式转换、泛型、

         upperbound、viewbound、contextBound

一、柯里化

1.1 定义:

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。

1.2 简单举例

package day03
 
class CurryingDemo {
 
}
object Contest{
 
  implicit val a = 100
 
}
object CurryingDemo{
 
  //柯里化
  def main(args: Array[String]): Unit = {
 
    import Contest.a
 
    val b = m1(3)(a)
 
    val result01 = m1(3)
    val result02 = m1(3)(4)
    val result03 = m2(8)(9)
 
    println(b)
    println("result01 : "+result01)
    println(result02)
    println(result03)
 
    println(ArraySum.sum)
 
  }
 
  def m1(x:Int)(implicit y:Int = 7) = x * y
  def m2(x:Int) = (y:Int) =>x * y
 
}
 
//数组后面值进行求和
object ArraySum{
 
  val arr = Array(("array",1),("scala",2),("java",3),("python",4))
 
  val sum = arr.foldLeft(0)(_ + _._2)
 
}

二、隐式转换

定义:我们想要扩展新功能的时候,scala提供了隐式转换机制和隐式参数帮我们解决诸如这样的问题。当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转化提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型。

简单举例:

package day03
 
import scala.io.Source
 
/**
  * 隐式转换举例
  *
  */
class RichIntDemo(val filepath:String) {
 
  def read() = {
    //读取到文件,返回String字符串
    Source.fromFile(filepath,"GBK").mkString("")
  }
 
}
object RichIntDemo{
  def main(args: Array[String]): Unit = {
 
    //1, to 方法是在 RichInt 防范里面
    val a = 1 to 10
    println(a)
 
    //2.1  显示转换:读取文件内容,并打印。
    val filepath:String = "C:/Users/Administrator/Desktop/c.txt"
    val content01 = new RichIntDemo(filepath).read()
    println("content01"+content01)
 
    //2.2  隐式转换:
 
    import day03.MyPredef.fileToRichFile
 
    val content02 = filepath.read()
    println("content02"+content02)
 
  }
}
 

三、泛型

3.1 简介

  • 泛型类、泛型函数
  • 泛型用于指定方法或类可以接受任意类型参数
  • 参数在实际使用时才被确定
  • 泛型可以有效地增强程序的适用性
  • 使用泛型可以使得类或方法具有更强的通用性

3.2 七种形式

[A<:] :上边界:表达了泛型的类型必须是"某种类型"或某种类型的"子类"

案例:override def toSet[B >: A]: Set[B] = {}

[A>:] :下边界:表达了泛型的类型必须是"某种类型"或某种类型的"父类"

案例:override def toSet[B >: A]: Set[B] = {}

[A<%] : view bounds可以进行某种神秘的转换,把你的类型在没有知觉的情况下转换成目标类型

可以认为view bounds是上下边界的加强和补充,语法为:"<%",要用到implicit进行隐式转换

“T:classTag”:相当于动态类型,你使用时传入什么类型就是什么类型

逆变和协变:-T和+T: +T可以传入其子类和本身(与继承关系一至)-T可以传入其父类和本身(与继承的关系相反)

案例:trait scala.collection.immutable.Map[K, +V] extends Iterable[(K, V)]

“T:Ordering” :表示将T变成Ordering[T],可以直接用其方法进行比大小,可完成排序等工作

[A]: 一般形式

 

简单实例进行说明:比较两个动物谁跑的快,speed大的被打印。在第(3)(4)中加了另外一个属性,就是age,age小的获胜被打印出来。

(1)实际使用协变实现

package day03
 
/**
  * 练习技术,隐式转换、隐式值、柯里化、泛型、内部类
  *        练习内容,比较两个动物的速度
  *
  *        实现过程:
  *            1,定义一个class动物类,构造器中包含动物名称和动物速度两个属性
  *            2,定义类,构造器中包含两个比较对象,写一个比较方法,利用的是Ordering方法中的gt方法进行比较。
  *            3,Ordering是如何进行比较的呢?继承Ordering特质。重写compare方法,规定,规则。
  *
  *
  *
  */
class SpeedEqual {
 
}
 
object ImplicitContext{
  implicit object OrderingAnimal extends Ordering[Animal]{
    override def compare(x: Animal, y: Animal): Int = if(x.speed > y.speed) 1 else -1
  }
 
}
 
class AnimalFirst[T:Ordering](val an1:T,val an2:T){
  def choose()(implicit ord:Ordering[T]) = if(ord.gt(an1,an2)) an1 else an2
}
 
class Animal(val name:String,val speed:Int){
  // toString方法
  override def toString: String = s"name: $name, speed: $speed"
}
 
 
object AnimalEquals{
 
  def main(args: Array[String]): Unit = {
 
    import ImplicitContext.OrderingAnimal
 
    val dog = new Animal("dog",200)
    val cat = new Animal("cat",100)
 
    val animalFirst = new AnimalFirst(dog,cat)
    val animal_king = animalFirst.choose()
    println(animal_king)
 
  }
 
}

(2)upperBound

package day03
 
/**
  * 泛型
  *    [B <: A] UpperBound 上界:B类型的上界是A类型。 即 B类型的父类是A类型
  *    [B >: A] LowerBound 下届:B类型的下界是A类型。 即 B类型的子类是A类型
  *    [B <% A] ViewBound 表示B类型要转换成A类型,需要一个隐式转换函数
  *    [B : A] ContextBound 需要一个隐式转换值
  *
  *    [-A, +B]
  *         [-A] 逆变,作为参数类型,如果A是B的子类,那么C[B]是C[A]的子类
  *         [+B] 协变,作为返回类型,如果A是B的子类,那么C[A]是C[B]的子类
  *   实现内容,比较谁的速度更快一点:
  *           [B <: A]  表示B是A的子类
  *
  */
 
//写一个比较的方法,而Comparable有比较的方法。那就可以作文他的子类进行
class SelectAnimal[T <: Comparable[T]]{
 
  def select(first:T,second:T): T ={
    if(first.compareTo(second)>0) first else second
  }
 
}
 
//写一个类,1为了声明属性。2为了继承(特质)Compareable实现其比较类
class Animal002(val name:String,val speed:Int) extends Comparable[Animal002]{
  override def compareTo(o: Animal002): Int = {
    this.speed-o.speed
  }
}
 
object UpperBound{
 
  def main(args: Array[String]): Unit = {
 
    val dog = new Animal002("dog",100)
    val cat = new Animal002("cat",99)
 
    val animalCompare = new SelectAnimal[Animal002]
    val animal_first: Animal002 = animalCompare.select(dog,cat)
    println(animal_first.name)
 
  }
}

(3)ViewBound

package day03
 
 
object ViewBound {
  def main(args: Array[String]): Unit = {
 
    import day03.MyPredef.selectAnimal2
 
    val dog01 = new Animal003("dog", 6, 188)
    val cat01 = new Animal003("cat", 5, 188)
 
    val view_ani = new ViewBound[Animal003]
 
    val animalSelect = view_ani.select(dog01, cat01)
    println(animalSelect.name)
 
  }
}
 
//想用viewBound来比较。进行A类型转换成B类型,声明一个viewBound类。注意的是 用[]来进行包裹。
class ViewBound[T <% Ordered[T]] {
 
  def select(first: T, second: T): T = {
    if (first > second) first else second
  }
 
}
package day03
 
//隐式转换
object MyPredef {
 
  implicit def fileToRichFile(filename:String) = new RichIntDemo(filename)
 
  implicit val selectAnimal2 =(an2:Animal003) => new Ordered[Animal003]{
    override def compare(that: Animal003): Int = {
      if(an2.speed == that.speed ){
        that.age - an2.age
      }else{
        an2.speed-that.speed
      }
 
    }
  }
}

(4)ContextBound

package day03
 
//
 
class ContextBound [T:Ordering]{
 
  def select(first:T,second:T): T ={
    val ord:Ordering[T] = implicitly[Ordering[T]]
    if (ord.gt(first,second)) first else second
 
  }
 
}
object ContextBound{
 
  def main(args: Array[String]): Unit = {
    val dog01 = new Animal003("dog", 6, 188)
    val cat01 = new Animal003("cat", 5, 188)
 
    import day03.MyPredef.selectAnimal2
 
    val animal = new ContextBound[Animal003]
    val animalSelect = animal.select(dog01,cat01)
    println(animalSelect.name)
  }
 
}
package day03
 
//隐式转换
object MyPredef {
 
  implicit object SelectAnimal extends Ordering[Animal003]{
    override def compare(x: Animal003, y: Animal003): Int =
      if(x.speed - y.speed == 0){
        y.age - x.age
      }else{
        x.speed -y.speed
      }
  }
 
 
}
目录
相关文章
|
Scala
173 Scala 隐式转换和隐式参数
173 Scala 隐式转换和隐式参数
34 0
|
6月前
|
SQL 分布式计算 编译器
Scala:高阶函数、隐式转换(四)
Scala:高阶函数、隐式转换(四)
53 0
|
6月前
|
分布式计算 Java 大数据
Scala:样例类、模式匹配、Option、偏函数、泛型(三)
Scala:样例类、模式匹配、Option、偏函数、泛型(三)
71 0
|
Java Scala
scala中的隐式转换和隐式参数
Scala提供的隐式转换和隐式参数功能,是非常有特色的功能。是Java等编程语言所没有的功能。它可以允许你手动指定将某种类型的对象转换成其他类型的对象,或是给一个类增加方法。通过这些功能,可以实现非常强大的功能。
74 0
scala中的隐式转换和隐式参数
|
大数据 Scala 开发者
大数据开发基础的编程语言的Scala的隐式转换
Scala是一种支持隐式转换的编程语言,它提供了一种很方便的方式来实现代码的扩展和重用。本文将介绍Scala中隐式转换的概念和用法,帮助开发者更好地理解和应用这门语言。
91 0
|
Java Scala
scala中的泛型
scala和Java一样,类和特质、方法都可以支持泛型。我们在学习集合的时候,一般都会涉及到泛型。
92 0
|
Java Scala 开发者
Scala 泛型介绍和应用实例2 | 学习笔记
快速学习 Scala 泛型介绍和应用实例2
Scala 泛型介绍和应用实例2 | 学习笔记
|
Scala
第6关:Scala函数柯里化和闭包
第6关:Scala函数柯里化和闭包
159 0
第6关:Scala函数柯里化和闭包
|
编译器 Scala
Scala系列之隐式转换和隐式参数
Scala系列之隐式转换和隐式参数5.1. 概念隐式转换和隐式参数是Scala中两个非常强大的功能,利用隐式转换和隐式参数,你可以提供优雅的类库,对类库的使用者隐匿掉那些枯燥乏味的细节。 5.2. 作用隐式的对类的方法进行增强,丰富现有类库的功能 object ImplicitDemo exten...
713 0