定义一个方法,其中包含一个隐式参数. 那么调用的时候可以不用把这个隐式参数传进去, 解释器会自己找一个用implicit定义的变量,不管这个变量名字叫啥,都会把这个变量传给方法中的隐式参数.

//定义一个方法,有一个隐式参数
scala> def person(implicit name : String) = name
person: (implicit name: String)String
//直接调用,出错,因为找不到隐式参数
scala> person
<console>:29: error: could not find implicit value for parameter name: Stringperson^
//定义一个隐式变量
scala> implicit val p = "mobin"
p: String = mobin
//再次执行,ok
scala> person
res7: String = mobin
//在定义一个隐式变量
scala> implicit val p1 = "mobin1"
p1: String = mobin1
//再次调用,出错,隐式参数太多,不知道用哪个
scala> person
<console>:33: error: ambiguous implicit values:both value p of type => Stringand value p1 of type => Stringmatch expected type Stringperson^
//定义一个方法,含有一个隐式参数
scala>  def person1(age:Int)(implicit name : String): String = name+age
person1: (age: Int)(implicit name: String)String
//找不到隐式参数
scala> person1(10)
<console>:26: error: could not find implicit value for parameter name: Stringperson1(10)^
//隐式参数也可以显式传入
scala> person1(10)("libai")
res2: String = libai10
//定义一个隐式变量
scala> implicit val a="doubi"
a: String = doubiscala> person1(10)
res4: String = doubi10scala> implicit val b="liubei"
b: String = liubei
//同样作用域隐式变量不能定义多个
scala> person1(10)
<console>:30: error: ambiguous implicit values:both value a of type => Stringand value b of type => Stringmatch expected type Stringperson1(10)^

隐式变量也可以定义在其他object

使用时导入即可

object Demo4 {def main(args: Array[String]): Unit = {import Test._print(person1(10))//dufu10}def person1(age:Int)(implicit name : String): String = name+age
}object Test{implicit val a: String ="dufu"
}

但是定义在class中是不行的

当然,定义在同一个object当然没问题的

object Demo4 {implicit val a: String ="dufu"def main(args: Array[String]): Unit = {print(person1(10))//dufu10}def person1(age:Int)(implicit name : String): String = name+age
}

一个稍微复杂的例子

如下,可以看出,sortBy方法有一个隐式参数,类型为Ordering[B],

  • 当B为内置类型时,比如String,会有内置的隐式参数完成
  • 当B为自定义类时,比如下面的自定义类Girl,就需要自己实现这个隐式参数(或者说自己创建这个隐式参数)
def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Repr
object SortDemo2 extends App {val conf: SparkConf = new SparkConf().setAppName("wordcount").setMaster("local")val sc = new SparkContext(conf)val rdd: Array[Girl] = Array(Girl(10, 156), Girl(6, 136), Girl(7, 176), Girl(9, 196))import Girl._//sortBy有一个隐式参数rdd.sortBy(x => x)(Ordering[Girl]).foreach(println)
}case class Girl(beauty: Int, height: Int) {}object Girl {//定义一个隐式变量,别看a这么多代码,本质也是个变量implicit val a: Ordering[Girl] = new Ordering[Girl]() {//实现compare方法override def compare(x: Girl, y: Girl): Int = {val rs: Int = y.beauty - x.beautyif (rs == 0) {return y.height - x.height}rs}}
}

换种写法,但是一般不这么写,隐式的参数,就是不想让你显式的传入.

object SortDemo2 extends App {val conf: SparkConf = new SparkConf().setAppName("test").setMaster("local")val sc = new SparkContext(conf)val rdd: Array[Girl] = Array(Girl(10, 156), Girl(6, 136), Girl(7, 176), Girl(9, 196))
//直接传入隐式参数.哪里需要就在哪里创建rdd.sortBy((x: Girl) => x)(new Ordering[Girl]() {//实现compare方法override def compare(x: Girl, y: Girl): Int = {//依据颜值进行排序val rs: Int = y.beauty - x.beautyif (rs == 0) {//颜值相同情况下依据身高进行排序return y.height - x.height}rs}}).foreach(println)
}
//创建自定义类Girl
case class Girl(beauty: Int, height: Int) {}

再比如

object _SortDemo {def main(args: Array[String]): Unit = {val conf: SparkConf = new SparkConf().setAppName("wordcount").setMaster("local")val sc = new SparkContext(conf)//创建5个学生的数组val stus: Array[Student] = Array(Student(1001, "zhangsan", 23, "f"),Student(1003, "lisi", 12, "f"),Student(1002, "wangwu", 40, "m"),Student(1002, "zhaoliu", 18, "f"),Student(1004, "niubi", 7, "m"))val stts: RDD[Student] = sc.parallelize(stus)val sorted: RDD[Student] =stts.sortBy(x =>x)sorted.foreach(println)}
}case class Student(sid: Int, name: String, age: Int, gender: String) {}
object Student {//定义一个隐式变量,可以用于某些需要隐式参数的方法,当然,前提是类型匹配implicit val suibian: Ordering[Student] =new Ordering[Student]{override def compare(x: Student, y: Student): Int = {val rs: Int =x.sid-y.sidif(rs==0){return x.age-y.age}rs}}
}

隐式参数的选择依据其类型

abstract class Monoid[A] {def add(x: A, y: A): Adef unit: A
}object ImplicitTest {//定义隐式变量,可以用于含有隐式参数的方法. 类型匹配的前提下implicit val stringMonid: Monoid[String] = new Monoid[String] {override def add(x: String, y: String): String = {x + y}override def unit: String = ""}
//定义隐式变量,可以用于含有隐式参数的方法. 类型匹配的前提下implicit val intMoninew: Monoid[Int] = new Monoid[Int] {override def add(x: Int, y: Int): Int = {x + y}override def unit: Int = 0}//定义隐式变量,可以用于含有隐式参数的方法. 类型匹配的前提下implicit val doubleMon: Monoid[Double] = new Monoid[Double] {override def add(x: Double, y: Double): Double = x + yoverride def unit: Double = 0.0}
//定义一个含有隐式参数的方法def sum[A](xs: List[A])(implicit m: Monoid[A]): A = {if (xs.isEmpty) m.unitelse m.add(xs.head, sum(xs.tail))}def main(args: Array[String]): Unit = {//依据参数类型自动选择隐式参数println(sum(List(1, 2, 3))) // 6println(sum(List("a", "b", "c"))) //abcprintln(sum(List(1.0, 2.0, 3.4))) //6.4}
}

也可以将隐式变量写在不同的object中,使用的时候导入即可

//隐式参数demo
abstract class Monoid[A] {def add(x: A, y: A): Adef unit: A
}object ImplicitTest {implicit val stringMonid: Monoid[String] = new Monoid[String] {override def add(x: String, y: String): String = {x + y}override def unit: String = ""}implicit val intMoninew: Monoid[Int] = new Monoid[Int] {override def add(x: Int, y: Int): Int = {x + y}override def unit: Int = 0}implicit val doubleMon: Monoid[Double] = new Monoid[Double] {override def add(x: Double, y: Double): Double = x + yoverride def unit: Double = 0.0}def sum[A](xs: List[A])(implicit m: Monoid[A]): A = {if (xs.isEmpty) m.unitelse m.add(xs.head, sum(xs.tail))}}object test extends App {//导入隐式参数import ImplicitTest._println(sum(List(1, 2, 3))) // 6println(sum(List("a", "b", "c"))) //abcprintln(sum(List(1.0, 2.0, 3.4))) //6.4
}

scala 隐式参数入门及应用相关推荐

  1. Scala隐式参数(隐式值)

  2. Scala入门到精通——第十九节 隐式转换与隐式参数(二)

    本节主要内容 隐式参数中的隐式转换 函数中隐式参数使用概要 隐式转换问题梳理 1. 隐式参数中的隐式转换 前一讲中,我们提到函数中如果存在隐式参数,在使用该函数的时候如果不给定对应的参数,则编译器会自 ...

  3. Scala入门到精通——第十八节 隐式转换与隐式参数(一)

    本节主要内容 隐式转换简介 隐式转换函数 隐式转换规则 隐式参数 1. 隐式转换简介 在Scala语言当中,隐式转换是一项强大的程序语言功能,它不仅能够简化程序设计,也能够使程序具有很强的灵活性.要想 ...

  4. scala入门-10 隐式转换、隐式参数、隐式类

    到目前为止,隐式转换是scala的重点和难点了,加油~ 我们先创建一个类名称叫Implicit.scala 再看一个隐式参数的例子: 上面的例子中使用了隐式参数,我们也可以明显的指明参数: 下面看一下 ...

  5. 7.scala初识 柯里化、隐式参数、隐式转换、视图边界、上界、下界、协变、逆变

    1.前言: 学过java我们都知道,java中的继承是对类的增强,java中的代理.装饰是对对象方法的增强.而在scala中,隐式转换和隐式参数是Scala中两个非常强大的功能,隐式的对类的方法进行增 ...

  6. 2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数

    目录 隐式转换和隐式参数 隐式转换 自动导入隐式转换方法 隐式转换的时机 隐式参数 隐式转换和隐式参数 隐式转换和隐式参数是scala非常有特色的功能,也是Java等其他编程语言没有的功能.我们可以很 ...

  7. 传递list对象作为参数_24.scala的隐式参数

    方法可以具有 隐式 参数列表,由参数列表开头的 implicit 关键字标记. 如果参数列表中的参数没有像往常一样传递, Scala 将查看它是否可以获得正确类型的隐式值,如果可以,则自动传递. Sc ...

  8. scala中的隐式转换、隐式参数和隐式类

    scala中的隐式转换.隐式参数和隐式类 @(SCALA)[scala] scala中的隐式转换隐式参数和隐式类 一隐式转换 1示例 2隐式转换的条件 二隐式参数 1示例 三隐式类 1示例 隐式转换是 ...

  9. scala 隐式转换与隐式参数

    隐式转换函数 指的是以implicit关键字声明的带有单个参数的函数,这种函数会自动引用,将值从一种类型转换为另一种类型.就是说如果类型不匹配时,会自动寻找一个隐式方法,把这个格式不匹配的事情解决掉. ...

最新文章

  1. 【MM】需求类型清单
  2. 首发:徐亦达老师的机器学习课件及下载(中文目录)
  3. 游戏中的整容术! 《Honey Select》捏人系统剖析
  4. sqoop——将mysql数据库的数据表导入到hdfs上
  5. MySQL语法解析和预处理(Parser Preprocessor)
  6. Fiori note automatic delete deletion scenario
  7. Jquery操作select小结
  8. linux用户开放crontab权限,linux – / etc / crontab权限
  9. ctd数据 matlab,基于auv的ctd数据处理方法
  10. Android 解析JSON
  11. 在组织中为IT部门构建小型冠军的最快方法
  12. 高光谱图像处理和分析软件(包含雷尼绍Renishaw wdf 文件导入解析功能)
  13. cass道路设计教程_如何用CASS搞定道路类土方工程计算?
  14. 现金支票打印模板excel_Word如何批量打印奖状?按下这个键,1分钟生成1000张
  15. java char表_char码值对应列表大全
  16. 乔布斯斯坦福毕业演讲,这是我听过最精彩的毕业演讲!
  17. grok java_Java Grok.match方法代码示例
  18. 3d建模软件安装教程,游戏建模必备软件推荐(收藏)
  19. 支付宝app支付功能-服务端的实现-python3版
  20. VMware虚拟机中安装苹果系统MacOS 10.12 Sierra

热门文章

  1. python结课报告_20193111 2019-2020《Python程序设计》实验4报告
  2. 4 安卓安装路径_安卓逆向——APK安装流程
  3. python定义空函数体_Python 2.2 定义函数
  4. 用Android Studio做一个超好玩的拼图游戏,附送超详细注释的源码
  5. php语句创建数据表,用mysql语句创建数据表详细教程
  6. oracle 表收缩,Oracle 收缩表大小 Oracle Shrink Table
  7. c 标签 foreach里面套choose做判断
  8. sftp mysql_Linux下搭建SFTP服务器
  9. 1.简述计算机硬盘如何保养,电脑硬盘的保养知识
  10. ipv6单播地址包括哪两种类型_IPv6基础介绍