• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Scala隐式转换和隐式参数

武飞扬头像
年轻即出发
帮助1

1  隐式转换

隐式转换函数是以implicit关键字声明的带有单个参数的函数。这种函数将会自动应用,将值从一种类型转换为另一种类型。

implicit def a(d: Double) = d.toInt
//不加上边这句你试试
val i1: Int = 3.5
println(i1)

2  利用隐式转换丰富类库功能

如果需要为一个类增加一个方法,可以通过隐式转换来实现。比如想为File增加一个read方法,可以如下定义:

class RichFile(val from: File) {
  def read = Source.fromFile(from.getPath).mkString
}
 
implicit def file2RichFile(from: File) = new RichFile(from)
 
val contents = new File("C:\\Users\\61661\\Desktop\\scala笔记.txt").read
println(contents)

有什么好处呢?好处就是你可以不修改原版本的代码而为原本的代码增加新功能。

3  隐式值

将name变量标记为implicit,所以编译器会在方法省略隐式参数的情况下去搜索作用域内的隐式值作为缺少参数。

implicit val name = "Nick"
def person(implicit name: String) = name
println(person)

但是如果此时你又相同作用域中定义一个隐式变量,再次调用方法时就会报错:出现二义性

implicit val name = "Nick"
implicit val name2 = "Nick"
def person(implicit name: String) = name
println(person)

4  隐式视图

1)  隐式转换为目标类型:把一种类型自动转换到另一种类型

def foo(msg : String) = println(msg)
implicit def intToString(x : Int) = x.toString
foo(10)

2)  隐式转换调用类中本不存在的方法

class Dog {
  val name = "金毛"
}
 
class Skill{
  def fly(animal: Dog, skill: String) = println(animal.name   "已领悟"   skill)
}
 
object Learn{
  implicit def learningType(s : Dog) = new Skill
}
 
object Main2 extends App{
  override def main(args: Array[String]): Unit = {
    import unit15.Learn._
    val dog = new Dog
    dog.fly(dog, "飞行技能")
  }
}

当然了,以上操作也可以定义在包对象中,即,在object Learn的外面再套一层,package,没问题的!

5  隐式类

在scala2.10后提供了隐式类,可以使用implicit声明类,但是需要注意以下几点:

--  其所带的构造参数有且只能有一个

--  隐式类必须被定义在“类”或“伴生对象”或“包对象”里

--  隐式类不能是case class(case class在定义会自动生成伴生对象与2矛盾)

--  作用域内不能有与之相同名称的标示符

object StringUtils {
  implicit class StringImprovement(val s : String){ //隐式类
    def increment = s.map(x => (x  1).toChar)
  }
}
object Main3 extends  App{
  import unit15.StringUtils._
  println("mobin".increment)
}

6  隐式的转换时机

1)  当方法中的参数的类型与目标类型不一致时

2)  当对象调用所在类中不存在的方法或成员时,编译器会自动将对象进行隐式转换

7  隐式解析机制

即编译器是如何查找到缺失信息的,解析具有以下两种规则:

1)  首先会在当前代码作用域下查找隐式实体(隐式方法、隐式类、隐式对象)。

2)  如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。类型的作用域是指与该类型相关联的全部伴生模块,一个隐式实体的类型T它的查找范围如下:

a)  如果T被定义为T with A with B with C,那么A,B,C都是T的部分,在T的隐式解析过程中,它们的伴生对象都会被搜索。

b)  如果T是参数化类型,那么类型参数和与类型参数相关联的部分都算作T的部分,比如List[String]的隐式搜索会搜索List的伴生对象和String的伴生对象。

c)  如果T是一个单例类型p.T,即T是属于某个p对象内,那么这个p对象也会被搜索。

d)  如果T是个类型注入S#T,那么S和T都会被搜索。

8  隐式转换的前提

1)  不能存在二义性

2)  隐式操作不能嵌套

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhichfj
系列文章
更多 icon
同类精品
更多 icon
继续加载