A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 余大麻 于 2019-2-14 08:49 编辑

柯里化
  • 柯里化是一个过程
  • 把一个参数列表中的多个参数, 转换为多个参数列表
  • 科里化可以支持隐式转换
[Scala] 纯文本查看 复制代码
object Currying {
  "正常方法"
  def m1(a: Int, b: Int): Int = a + b

  "柯里化方法"
  def m2(a: Int)(b: Int) = a + b
  def m3(a: Int)(b: Int, c: Int) = a + b + c
  def m4(a: Int, b: Int)(c: Int, d: Int) = a + b + c + d

  def main(args: Array[String]): Unit = {
    println("正常方法调用:" + m1(10, 20))
    println("柯里化方法调用:" + m2(10)(20))
    println("柯里化方法调用:" + m3(10)(20, 30))
    println("柯里化方法调用:" + m4(10, 20)(30, 40))
  }
}

隐式参数
  • 用 implicit 关键字修饰的参数,就是隐式参数
  • 隐式参数的值从哪儿取
    • 从上下文环境中,最多找到一个和隐式参数类型一致,且用implicit修饰的变量,如果找到多个则报错
    • 如果上下文环境中没有,则使用默认值
    • 如果找不到,也没有默认值,则报错
  • implicit 只能作用于最后一个参数列表,一个参数列表中只能由一个 implicit 关键字
    • 关键字只能放在最后一个参数列表中,而且修饰该参数列表中的所有参数

[Scala] 纯文本查看 复制代码
object ImpDemo {
  implicit val defalut1: Int = 20
  // implicit val defalut2: Int = 30
  implicit val defalut3: Double = 10

  def m1(a: Int)(implicit b: Int = 10): Int = {
    if (a > b) a else b
  }

  def m2(a: Int)(implicit b: Int, c: Double): Double = a + b + c

  def main(args: Array[String]): Unit = {
    println(m1(5))
    println(m1(5)(30))
    println(m2(10))
  }
}

隐式转换
  • 主要指隐式方法和隐式函数
[Scala] 纯文本查看 复制代码
object ImpMethod {
  implicit def str2int(str: String): Int = Integer.parseInt(str)

  def main(args: Array[String]): Unit = {
    println(1 to 3)
    "这里发生了隐式转换,这里调用了RichInt的方法"
    "implicit 修饰的方法,方法参数是Int,返回值是RichInt"
    "当Int 类型上调用to方法,Int上没有这个方法,但是RichInt上有,发现有隐式方法从Int->RichRint"
    println(1.to(3))
    val x: Int = "123"
    println(x)
  }
}

[Scala] 纯文本查看 复制代码
import java.io.File
import scala.io.Source
class RichFile(f: File) {
  def read(): String = Source.fromFile(f).getLines().mkString("\r\n");
}
object RichFile {
  // 隐式转换
  implicit def file2RichFile(f: File): RichFile = new RichFile(f)
  def main(args: Array[String]): Unit = {
    val path: String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
    val f = new File(path)
    val lines = f.read()
    println(lines)
  }
}

  • 如果隐式方法和隐式函数都存在,优先使用函数
[Scala] 纯文本查看 复制代码
class RichFile(f: File) {
  def read(): String = Source.fromFile(f).getLines().mkString("\r\n");
}
object RichFile {
  // 隐式转换
  implicit def file2RichFile(f: File): RichFile = new RichFile(f)
  implicit val file2RichFile2 = (f: File) => {
    println("调用函数")
    new RichFile(f)
  }
  def main(args: Array[String]): Unit = {
    val path: String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
    val f = new File(path)
    val lines = f.read()
    println(lines)
  }
}

  • 可以导入外部的隐式转换 ,类和object导入方式不一样
[Scala] 纯文本查看 复制代码
import java.io.File
class MyImpl {
  implicit def file2RichFile(f: File): RichFile = new RichFile(f)
}
object MyImpl {
  implicit def file2RichFile(f: File): RichFile = new RichFile(f)
}

[Scala] 纯文本查看 复制代码
class RichFile(f: File) {
  def read(): String = Source.fromFile(f).getLines().mkString("\r\n");
}
object RichFile {
  "引入 object 的隐式方法"
  import MyImpl.file2RichFile

  "引入 class 的隐式方法"
  private val imp = new MyImpl
  import imp.file2RichFile

  def main(args: Array[String]): Unit = {
    val path: String = "C:/Users/unkonw_yu/Desktop/scala/rating.json"
    val f = new File(path)
    val lines = f.read()
    println(lines)
  }
}

泛型
[Scala] 纯文本查看 复制代码
abstract class Message[T](msg: T) {
    def getMsg(): T = msg
}
class IntMsg(msg: Int) extends Message(msg)
class StrMsg(msg: String) extends Message(msg)

object TestMsg {
    def main(args: Array[String]): Unit = {
        val msg1 = new IntMsg(123)
        println(msg1.getMsg())
        val msg2 = new StrMsg("hello")
        println(msg2.getMsg())
    }
}

[Scala] 纯文本查看 复制代码
class Clothes[ColorTypes](val color: ColorTypes)

"枚举"
object ColorTypes extends Enumeration {
    type CT = Value
    val RED = Value(0)
    val BLACK = Value(1)
    val GREEN = Value(2)
}

object TestMsg {
    def main(args: Array[String]): Unit = {
        val colthes1 = new Clothes[ColorTypes.Value](ColorTypes.RED)
        val colthes2 = new Clothes[CT](ColorTypes.GREEN)
        println(colthes1.color)
        println(colthes2.color)
    }
}

比较器
  • Java 中的比较器
    • Comparable
    • Comparator
  • scala中的比较器
    • Ordered --> Comparable
    • Ordering --> Comparator

[Scala] 纯文本查看 复制代码
import java.util
import java.util.Collections

class Student(val name: String, val age: Int, val fv: Int) extends Ordered[Student] {
    override def compare(that: Student): Int = this.fv - that.fv
    override def toString: String = s"${name},${age},${fv}"
}

object Student {
    def main(args: Array[String]): Unit = {
        val sList = new util.ArrayList[Student]()
        
        val s1 = new Student("zs",23,999)
        val s2 = new Student("li",24,998)
        val s3 = new Student("ww",25,997)
        
        sList.add(s1)
        sList.add(s2)
        sList.add(s3)
        
        Collections.sort(sList)
        println(sList)
        
        Collections.sort(sList,new Ordering[Student]{
            override def compare(x: Student, y: Student): Int = y.fv - x.fv
        })
        println(sList)
    }
}

泛型约束上界
  • Java
    • <T extends P>
    • <? extends P>
  • Scala
    • T <: P
[Scala] 纯文本查看 复制代码
任意类型比较"
class ComparTest[T](t1: T, t2: T) {
  def myEquals() = t1 == t2
}
"Comparable 的子类"
class ComparaTest2[T <: Ordered[T]](t1: T, t2: T) {
  def myEquals() = t1 compareTo t2
}
object ComparTest {
  def main(args: Array[String]): Unit = {
    val s1 = new Student("zs", 23, 999)
    val s2 = new Student("li", 24, 998)

    val comp1 = new ComparTest[Student](s1, s2)
    println(comp1.myEquals())
    val comp2 = new ComparTest[Int](1, 2)
    println(comp2.myEquals())

    "报错,Int没有混入Ordered特质"
    val comp3 = new ComparaTest2[Int](1, 2)
    println(comp3.myEquals())

    "正常运行"
    val comp4 = new ComparaTest2[Student](s1,s2)
    println(comp4.myEquals())
  }
}

下界
[Scala] 纯文本查看 复制代码
object LowerBounds {
    val f1 = (x: Int, y: Int) => x + y
    val f2 = (a: AnyVal, b: AnyVal) => a.asInstanceOf[Int] + b.asInstanceOf[Int]
    val f3 = (a: Any, b: Any) => a
    val f4 = (a: Any, b: AnyRef) => a
    val f5 = (a: AnyRef, b: AnyRef) => a

    def main(args: Array[String]): Unit = {
        val arr = Array(1, 3, 5, 7, 9)
        // def reduce[A1 >: A]
        val res1 = arr.reduce(_ + _)
        val res2 = arr.reduce(f1)
        // AnyVal 是 Int 的父类,可以传递
        val res3 = arr.reduce(f2)
        // Any 是 Int 的顶级父类,可以传递
        val res4 = arr.reduce(f3)
        
        // AnyRef 不是 Int 的父类,调用失败
        // val res5 = arr.reduce(f4)
        // val res6 = arr.reduce(f5)
    }
}


协变逆变
[XML] 纯文本查看 复制代码
[T]  正常的泛型      不变
    [T <: Test]                上界
    [T >: Test]                下界
[+T]                            协变
[-T]                                逆变

[Scala] 纯文本查看 复制代码
class Card[T] {}
class Card[+T] {}
class Card[-T] {}

class Metting[T] {
  def metting(c: Card[T]): Unit = println("人们代表大会")
}

// 层级关系
class ChangWei

class Leader extends ChangWei

class Flower extends Leader

object Card {
  def main(args: Array[String]): Unit = {
    val metting = new Metting[ChangWei]()

    val changweiCart = new Card[ChangWei]
    val leaderCart = new Card[Leader]
    val flowerCart = new Card[Flower]

    "class Card[T]"
    metting.metting(changweiCart)
    "下面的会报错"
    // metting.metting(leaderCart)
    // metting.metting(flowerCart)

    "class Cart[+T],都不会报错"
    metting.metting(changweiCart)
    metting.metting(leaderCart)
    metting.metting(flowerCart)

    "class Cart[-T]"
    val leaderMetting = new Metting[Leader]
    leaderMetting.metting(changweiCart)
    leaderMetting.metting(leaderCart)
    "下面代码会报错"
    // leaderMetting.metting(flowerCart)
  }
}

CallByName 和 CallByValue
  • 函数调用中的两种形式
    • CallByName(传名调用)
      • 传递的参数,在调用的时候才会真正的执行
    • CallByValue(传值调用)
      • 先计算调用的结果,然后再传递


[Scala] 纯文本查看 复制代码
object CallByNameAndValue {
  def getCurTime() ={
    println("调用 method")
    System.currentTimeMillis()
  }
  def callByValie (time:Long): Long = {
    println("call by value")
    time
  }
  def callByName(time: => Long): Long = {
    println("call by name")
    time
  }
  def main(args: Array[String]): Unit = {
    "先执行getCurTime获取当前时间,然后传递给callByValue方法"
    callByValie(getCurTime())
    "先执行callByName方法,当需要用到参数的时候,才取计算结果"
    callByName(getCurTime())
  }
}





0 个回复

您需要登录后才可以回帖 登录 | 加入黑马