`
bit1129
  • 浏览: 1067637 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【Scala八】Scala核心二:隐式转换

 
阅读更多

Implicits work like this: if you call a method on a Scala object, and the Scala compiler does not see a definition for that method in the class definition for that object, the compiler will try to convert your object to an instance of a class that does have that method defined

 

 

隐式转换是Scala类型系统的强大特性之一,使得静态类型动态化,为现有类库添加功能。Scala的隐式转换,有三种:

  • 隐式函数
  • 隐式参数
  • 隐式类

隐式转换的规则:

  • 如果代码无需隐式转换即可通过编译,则不会引入隐式转换
  • 隐式转换只会匹配一次,即隐式转换至多发生一次
  • 存在二义性的隐式转换报错,

 

 

在期望隐式转换发生作用的时候,必须告诉Scala编译器,隐式转换背后起作用的实现逻辑在哪里?这个实现逻辑称为作用域或者为上下文Context

 

一、隐式函数

 

增强一个类,添加本不存在的方法,implicit作用于函数,称之为隐式函数

 

package spark.examples.scala

//假如Arithmetic是已有的类库中的类,仅仅提供add函数
class Arithmetic {
  def add(x: Int, y: Int): Int = {
    x + y
  }
}

//=========================================
//下面是增强Arithmetic类,添加一个subtract方法
//=========================================

class RichArithmetic(val arithmetic: Arithmetic) {
  def substract(x: Int, y: Int) = {
    x - y
  }
}

//转换的逻辑,隐式方法
object ArithmeticToRichArithmetic {
  //将Arithmetic转换为RichArithmetic
  //Arithmetic对象上可以直接调用RichArithmetic定义的方法
  implicit def arithmeticToRichArithmetic(arithmetic: Arithmetic) = {
    new RichArithmetic(arithmetic)
  }
}

object ImplicitDemo {
  def main(args: Array[String]) {
    import ArithmeticToRichArithmetic._ //引用方法
    val a = new Arithmetic
    println(a.add(11, 21))
    println(a.substract(21,11)) //substract不属于Arithmetic
  }


}

 

 

二、隐式参数:

 

package spark.examples.scala

object ObjectA {
    def print(content: String)(implicit prefix : String) {
      println(content + "," + prefix)
    }
}

//ObjectA隐式转换的作用域
object ObjectAWrapper {
  implicit val DEFAULT_OBJECT_A_STRING = "ObjectA"
}

object ImplicitArgument {
  def main(args : Array[String]) {
    ObjectA.print("ABC")( "DEF")
    import  ObjectAWrapper._ //Error: not enough argument if this line doesn't exist
    //为String类型的参数隐式的提供DEFAULT_OBJECT_A_STRING值
    ObjectA.print("ABC")
    ObjectA.print("ABC")( "XYZ")
  }
}

 

隐式参数的应用

如下代码出错:

class A[T] {
  def min(a: T, b: T) {
    if (a < b) a else b //泛型类T没有定义<方法
  }
}

object ImplicitArgument {
  def main(args : Array[String]) {
    val a = new A[Int]();
    a.min(10,11)
  }
}

 

 

package spark.examples.scala


class A[T] {
  //这里相当于为T指定约束,即T必须能够隐式转换到Ordered
  //T能够隐式转换到Ordered,那么对类型T的变量使用<操作时,将隐式地将T转换为Ordered类型的变量,然后调用Ordered类型的<方法
  //T隐式转换到Ordered,需要预先定义
  def min(a: T, b: T) (implicit  order: T=>Ordered[T]) = {
    if (a < b) a else b
  }
}

object ImplicitArgument2 {
  def main(args : Array[String]) {
    val a = new A[Int]();
    println(a.min(10,11)) //Scala已经实现了Int到Ordered的隐式转换,否则3 < 4做不了
    class B {}

    /** 报错的原因是No implicit view available from B => Ordered[B].即B没有定义到Ordered的隐式转换,所以报错
    val b = new A[B]() //
    b.min(new B(), new B())
    **/
  }
}

 

三、隐式类

增强一个类型

 

隐式类约束

  • 隐式类必须有一个带一个参数的主构造函数
  • 必须定义在另一个class/object/trait里面(不能独立定义)
  • 隐式类构造器只能带一个不是implicit修饰的参数
  • 作用域中不能有与隐式类类型相同的成员变量,函数以及object名称
package spark.examples.scala

class B {
  def add(x: Int, y: Int) = {
    x + y
  }
}

object ImplicitClassContext {

  //隐式类,可以为一个类型(参数的类型)提供方法
  //为主构造函数指定的类型进行增强
  implicit class RichB(arg: B) {

    def multiply(x: Int, y: Int) = {
      x * y
    }

  }

}

object ImplicitClass {
  def main(args: Array[String]) {
    import ImplicitClassContext._
    val b = new B();
    println(b.multiply(3, 4))
  }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    scala-2.12.6.tgz

    Scala还引入了一些独特的语言特性,如特质(Traits)、隐式转换和case类,这些帮助开发者实现更简洁、更具表达力的代码。 10. 社区与文档: Scala有一个活跃的社区,提供了丰富的开源库和工具,以及详尽的官方...

    Scala程序设计第二版

    5. **类型系统**:Scala拥有丰富的类型系统,包括类型推断、类型类、隐式转换等。这部分内容对于理解Scala代码的运行机制至关重要。 6. **Actor模型和并发编程**:Scala内置了Akka库,提供了基于Actor模型的并发...

    Scala最新官方下载包(官方的下载真的慢)

    9. **复合性管理**:Scala通过特质、包对象和隐式转换等机制,帮助开发者有效地管理复杂的系统。 10. **Dotty编译器**:虽然这里提到的是Scala 2018.1.8版本,但值得注意的是,Scala社区后来开发了Dotty编译器,...

    scala 案例

    11. ** implicits**:隐式转换和隐式参数是Scala中的一种高级特性,允许在上下文中透明地引入额外的功能。 通过分析这个"Scala案例",你将有机会实践这些概念,并了解如何在实际项目中运用Scala。学习这些知识点...

    Scala for the Impatient/快学Scala英文版.第二版 + Programming.in.Scala/Scala编程英文版

    1. **类型系统**:Scala的强类型系统支持隐式转换和类型推断,使得代码更加简洁。 2. **函数式编程**:介绍了高阶函数、柯里化、尾递归、模式匹配和不可变数据结构等概念。 3. **面向对象编程**:探讨了类、对象、...

    尚硅谷大数据之Scala语言核心编程.pdf

    对于变量类型转换,书中提供了隐式转换和强制类型转换的方法,并对值类型和String类型之间的转换进行了说明。标识符的命名规范也是本书的重点之一,包括了命名概念、规则、举例说明和命名注意事项。 第三章主要介绍...

    韩顺平_Scala语言核心编程 .zip

    此外,Scala还有模式匹配、类型别名、隐式转换等功能,增强了类型系统的灵活性。 4. **表达式导向**:Scala鼓励使用表达式而不是语句,这使得代码更加简洁。例如,if-else表达式可以返回一个值,而不仅仅是执行一个...

    scala入门精华讲义

    3. 隐式转换:Scala支持隐式转换,允许在特定上下文中将一个类型转换为另一个类型,提高代码的简洁性。 三、函数式编程概念 1. 高阶函数:如前所述,函数可以作为一等公民,可以赋值给变量、作为参数或返回结果。 ...

    Scala(Scala)所谓的:您如何称呼它?...对于Scala(Scala)

    此外,Scala还支持类型类和隐式转换,提供了更灵活的类型系统。 2. **面向对象编程**:Scala支持传统的类和对象,但更进一步,它引入了特质(trait),这是一种可以被继承和组合的轻量级接口,类似于Java的接口和...

    scala sdk .......

    10. **Type System**:Scala的类型系统非常灵活,支持类型推断、隐式转换和泛型,帮助开发者编写出类型安全且易于理解的代码。 总的来说,Scala SDK为开发人员提供了丰富的工具和库,旨在提升开发效率,支持复杂...

    Programming in Scala 2nd Edition

    6. **高级特性**:涵盖Scala的一些更高级特性,比如模式匹配、隐式转换、反射等。 7. **标准库和框架**:介绍了Scala的标准库以及常用的框架,如Play Framework、Akka等。 8. **最佳实践和设计模式**:提供了一些...

    Programming In Scala 中文版及英文版

    10. **隐式转换**:Scala的隐式转换可以在适当的时候自动将一个类型转换为另一个类型,简化了代码,但也需要谨慎使用以防止意外的类型转换。 **进阶知识点** 11. **Scaladoc**:Scala的文档生成工具,用于创建API...

    最好的scala学习 课件

    这部分还会讲解伴生对象(companion object)和隐式转换,这些特性使得Scala的面向对象设计更加灵活。 "Scala进阶之路-part04-Akka Actor.pdf"专注于Akka框架,这是Scala中用于构建分布式、容错系统的工具。Actor...

    scala-docs-2.11.8.rar

    **一、Scala核心概念** 1. **类型系统**:Scala的强类型系统允许静态类型检查,确保程序的健壮性。它还支持类型推断,使得代码更简洁。 2. **模式匹配**:Scala提供了强大的模式匹配功能,可以用于解构复杂数据结构...

    scala 2.12.4

    它的类型系统是富有表达力的,允许隐式转换和类型推断,使得代码更加简洁。 2. **面向对象编程**:Scala支持类、对象和继承,与Java类似。然而,它还引入了特质(Traits),这是一种更灵活的实现接口和多重继承的...

    Scala Overview

    8. 隐式转换:隐式转换允许在适当的情况下自动将一个类型的实例转换为另一个类型的实例,简化了代码,并支持类型系统的扩展。 9. 闭包和匿名函数:Scala中的闭包是第一类的,这意味着它们可以被赋值、作为参数传递...

    Effective Scala中文版

    7. **隐式转换与上下文绑定**:Scala的隐式转换和上下文绑定是其一大特色,它们可以用来解决类型转换的繁琐和简化API。但隐式转换需要谨慎使用,防止引入难以调试的问题。 8. **对象与模块化**:Scala中的对象和...

Global site tag (gtag.js) - Google Analytics