Scala - 隐式转换

均衡侠
• 阅读 1781

有时候我们看scala代码的时候,会发现明明没有这个类的类型或者函数,甚至是没有这个类,编译器不仅没有报错,程序还可以正常运行,其实这里就用到了scala的隐式转换。

隐式函数

当我们调用一个对象的方法的时候,但是这个对象并没有这个方法,此时就会触发隐式转换,会把这个对象偷偷的转换为具有这个方法的对象。
比如下面的例子,小鸡可以走路也可以跑,但是它也想像小鸟一样飞,但是它有没有这个功能。我们可以在不对小鸡整改的基础上,引入ChickenImplicit,让小鸡可以隐式的调用Bird的fly方法,让它可以像小鸟一样飞。

object ImplicitDemo1 {
  def main(args: Array[String]): Unit = {
    import ChickenImplicit._
    val chicken = new Chicken()
    chicken.work()
    chicken.run()
    // 隐式转为Bird,并调用Bird的fly方法
    chicken.fly()
  }
}

class Chicken() {
  def work(): Unit = {
    println("小鸡在走")
  }

  def run(): Unit = {
    println("小鸡在跑")
  }
}

class Bird {
  def fly(): Unit = {
    println("小鸟在飞")
  }
}

object ChickenImplicit {
  implicit def chicken2Bird(c: Chicken): Bird = new Bird()
}

上面是额外的定义ChickenImplicit,但是有时候我们可以直接在同一个类里定义,这样局不用加import,具体用哪种还是要看实际场景。

object ImplicitDemo2 {
  def main(args: Array[String]): Unit = {
    val chicken = new Chicken2()
    chicken.work()
    chicken.run()
    // 隐式转为Bird,并调用Bird的fly方法
    chicken.fly()
  }

  implicit def chicken2Bird(c: Chicken2): Bird2 = new Bird2()
}

class Chicken2() {
  def work(): Unit = {
    println("小鸡在走")
  }

  def run(): Unit = {
    println("小鸡在跑")
  }
}

class Bird2 {
  def fly(): Unit = {
    println("小鸟在飞")
  }
}

隐式参数

比如我们要调用方法,打印我们传递的参数,我们是这样写的:

def main(args: Array[String]): Unit = {
    printInfo1("aaa") // aaa
}

def printInfo1(str: String): Unit = {
    println(str)
}

如果我们调用方法的时候,如果不想传递参数,我们可以这样:
在方法里指定默认值

def main(args: Array[String]): Unit = {
    printInfo2("bbb") // bbb
    printInfo2() // default
}

def printInfo2(str: String = "default"): Unit = {
    println(str)
}

如果通过隐式参数,那我们就可以这样:
这里的方法不加括号也是可以的。由于是通过类型来匹配隐式值的,所以在一个作用域中,同一个类型只能有一次,并且他的优先级高于默认的,所以没有传递参数的时候,打印的implicit。

def main(args: Array[String]): Unit = {
    implicit val str: String = "implicit"
    printInfo3("ccc") // ccc
    printInfo3() // default
    printInfo3 // implicit
}

def printInfo3(implicit str: String = "default"): Unit = {
    println(str)
}

总结

当我们需要隐式转换的时候,我们就需要用implicit关键字。
隐式转换的时候,他会先全局的查找是否有匹配的方法或者参数,如果没有再考虑隐式转换。
由于隐式参数是根据类型的,所以同一作用域不能定义多个同一个类型的,并且默认值是优先于默认的。

点赞
收藏
评论区
推荐文章
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧 (一)
AC系列1、号的隐式类型转换使用js3//31,2,3.slice(1)//将3转换为了32、日期的转换jsconstaddDaysToDate(date,n)constdnewDate(date);d.setDate(d.getDate()n);returnd.toISOS
疯震震 疯震震
4年前
IntentFilter匹配规则
1、Activity启动方式我们知道,启动Activity分为两种,显式调用和隐式调用。显式调用需要明确指定被启动对象的组件信息,包括包名和类名。隐式调用不需要指定组件信息,但需要匹配目标组件的IntentFilter中所设置的过滤信息。2、IntentFilterIntentFilter中的过滤信息包括:action、category、data。为了匹配
Wesley13 Wesley13
3年前
JS函数高级
原型与原型链所有函数都有一个特别的属性:prototype:显式原型属性所有实例对象都有一个特别的属性:__proto__:隐式原型属性显式原型与隐式原型的关系函数的prototype:定义函数时被自动赋值,值默认为{},即用为原型对象
Stella981 Stella981
3年前
Scala系统学习(三):Scala基础语法
如果您熟悉Java语言语法和编程,那么学习Scala将会很容易。Scala和Java之间最大的句法差异在于行结束字符的分号(;)是可选的。当编写Scala程序时,它可以被定义为通过调用彼此的方法进行通信的对象的集合。现在我们简单地看一下类,对象,方法和实例变量的含义。对象 对象有状态和行为。一个对象是类的一个实例。例如狗有状态
Wesley13 Wesley13
3年前
C++类型转换
隐式转换在赋值给一个兼容类型会出现隐式类型转换.比如下面这个例子.shorta2000;intb;ba;在以上例子中.值从short自动提升到int,这是标准转换。标准转换影响基本数据类型,它在类型数字类型之间(short to int, int to float, double t
Stella981 Stella981
3年前
ECMAScript——JavaScript的核心
   JavaScript(简称:JS)是一种动态类型、弱类型的直译式脚本语言。也就是说它的数据类型不需要声明,不同类型之间会隐式转换为被赋值的类型。它不需要编译,直接由浏览器解释执行。JavaScript由ECMAScript(简称:ES)、DOM、BOM三大部分组成:ECMAScript规定了语言的语法和基本对象;DOM(文本对象模型)处理网页的节
Wesley13 Wesley13
3年前
Scala一分钟小课堂
ValueClasses主要用于扩展已有类的方法和创建类型安全的数据类型,功能上类似隐式转换,但是在运行时比隐式转换更节省内存。所有的ValueClasses都继承自AnyVal,例如:classWrapper(valunderlying:Int)extendsAnyVal扩展已有类的方法结合 implicit
Stella981 Stella981
3年前
Scala函数式对象
有理数类的表示实现规范:支持有理数的加减乘除,并支持有理数的规范表示1.定义Rational首先,考虑用户如何使用这个类,我们已经决定使用“Immutable”方式来使用Rational对象,我们需要用户在定义Rational对象时提供分子和分母。classRation
Wesley13 Wesley13
3年前
C++重载双目运算符(2)(对象与数之间)
有两种方法:(1)采用重载双目运算符方式(2)1.类型转换函数(将类的对象转换为其他数据类型)2.转换构造函数(将其他类型转换为类的对象)(仍然要配合重载双目运算符的方式,因为最终实现的是类的两个对象相加)(注意:类型转换函数和转换构造函数不可同时使用,会出现二
Wesley13 Wesley13
3年前
C++ 拷贝构造函数和赋值运算符
  这篇文章主要介绍拷贝构造函数和赋值运算符的区别,以及在什么时候调用拷贝构造函数,什么情况下调用赋值运算符。      拷贝构造函数和赋值运算符在默认情况下(用户没有定义,但是也没有显示的删除),编译器会自动隐式生成一个拷贝构造函数和赋值运算符,但用户可以使用delete来指定不生成拷贝构造函数和赋值运算符,这样的对象就不能通过值传递,也
小万哥 小万哥
1年前
C 语言:类型转换与常量的细致理解
C语言中的类型转换有时,您必须将一种数据类型的值转换为另一种类型。这称为类型转换隐式转换当您将一种类型的值分配给另一种类型的变量时,编译器会自动进行隐式转换。例如,如果您将一个int值分配给一个float类型:c//自动转换:inttofloatfloat