• scala隐式转换


    隐式转换--基本

    // 关键字:implicit
    // 隐式函数必须要在作用域范围内定义
    // 隐式转换函数的 函数名自定义
    // 隐式函数可以有多个,但是不能有重复的(函数名不能有重复,参数不能有重复)
    // 代码中有下划线的地方表示使用了隐式转换
    implicit def f1(d: Double): Int { d.toInt}  // 将double类型数据转换为int型
    implicit def f2(d: Float): Int { d.toInt}
    
    // 将Double或Float数据赋值给 int 型,调用了隐式转换
    val num: Int = 3.5 // 底层编译 f1$1(3.5)
    
    /////////////////////////////////////////////////////////////////////////////
    // 可以通过隐式行数丰富类库的功能,比如
    // 定义一个ms对象,只有insert方法
    class MS{
        def insert(): Unit = {
            println("insert")
        }
    }
    
    // 再定义一个db对象,有delete方法
    class DB {
        def delete(): Unit = {
            println("delete")
        }
    }
    
    // 定义隐式函数,返回 DB对象
    implicit def addDelete(ms: MS): DB = {
        new DB
    }
    
    val ms = new MS
    ms.insert()  // ms对象的方法
    ms.delete()  // 隐式函数中的db的方法
    
    

    隐式转换--进阶

    隐式参数优先级
    1、传入值 > 隐式值 > 默认值
    2、在隐式匹配时候,不能同时匹配多个
    3、如果3个一个都没有,就会报错

    // 定义字符串隐式值为 jack~
    implicit val str1: String = "jack~"
    // 参数使用了隐式变量,其值为上面定义的隐式变量
    def hello(implicit name: String): Unit = {
        println("hello " + name)
    }
    // 不用传入参数,即可输出数据:hello jack~
    hello
    
    ////////////////////////////////////////////
    
    implicit val str1: String = "jack~"
    // 参数中的 隐式变量使用了默认值,其优先级低于隐式值
    def hello(implicit name: String = "scala"): Unit = {
        println("hello " + name)
    }
    // 不用传入参数,输出数据:hello jack~
    hello
    
    
    ////////////////////////////////////////////
    
    implicit val name: Int = 10
    // 参数中匹配不到隐式值,会使用默认值
    def hello(implicit name: String = "scala"): Unit = {
        println("hello " + name)
    }
    // 不用传入参数,输出数据:hello jack~
    hello
    
    
    ////////////////////////////////////////////
    
    implicit val str1: String = "jack~"
    def hello(implicit name: String): Unit = {
        println("hello " + name)
    }
    // 传入值,优先级大于隐式值,输出数据:hello scala
    hello("scala")
    

    隐式转换--高阶

    隐式类

    // 隐式类必须在类、包对象、或伴生对象里面,不能单独在外面(顶级),因为其作用域不能确定
    // 隐式类不能用于 样例类
    
    
    class Ms{
        def sayOk():Unit = {
            println("sayOk")
        }
    }
    
    
    def main() = {
        implicit class db(val m: Ms) {
            def addSuffix(): String = {
                m + " scala"
            }
        }
        
        val ms new Ms  //创建一个Ms实例
        ms.sayOk()  // 调用自己的方法
        ms.addSuffix()  // 这个是隐式类的方法,因为传入了Ms后,创建了实例包含了此方法
    }
    
    

    其他

    隐式转换的时机

    1、当方法中的参数类型与目标类型不一致时
    2、当对象调用所在类中不存在的方法或成员时,编译器会自动将对象进行隐式转换(根据类型)

    隐式转换的陷阱

    1、不能存在二义性,即多个隐式
    2、不能嵌套使用:即隐式函数A如果是将小数转换为int,在隐式函数A中,不能使用 int=小数的情况。

  • 相关阅读:
    剑指Offer
    剑指Offer
    剑指Offer
    选书
    马的遍历
    从事效应
    魔性的素数环1~20 自带解释~
    [POJ1236]Network of Schools(并查集+floyd,伪强连通分量)
    [HDOJ3974]Assign the task(建树胡搞)
    [HDOJ4027]Can you answer these queries?(线段树,特殊成段更新,成段查询)
  • 原文地址:https://www.cnblogs.com/jaysonteng/p/14198064.html
Copyright © 2020-2023  润新知