精华内容
下载资源
问答
  • 隐式转换

    2021-05-25 11:50:09
    隐式转换开荒2.1 隐式转换函数 参数RichFile2.2 隐式类2.3 隐式解析机制三.回归主题 一. 生产问题背景 如上就是此blog产生的背景, Spark SQL 中, DF.select() select 报错 不能导入 spark sql Cannot resolve...

    一. 生产问题背景

    在这里插入图片描述
    如上就是此blog产生的背景,

    Spark SQL 中,
    	DF.select()
    
    select 报错 不能导入
    	spark sql Cannot resolve overloaded method 'select'
    
    咨询大佬后,隐式转换的原因 ,导入Spark的隐式转换后即可
    	import spark.implicits._
    

    二. 隐式转换开荒

    在这里插入图片描述

    没有隐式转换,只能从 精度较高的----->精度低的

    在这里插入图片描述
    但是从 精度低-----> 精度高的。就会报错

    在这里插入图片描述

    2.1 隐式转换函数 参数

    解决方案就是自己定义一个隐式转换函数,double2int。这个隐士函数的功能也需要是唯一的

    用强转换也行,那隐士转换可有可无?

    RichFile
    import java.io.File
    import scala.io.Source
    
    object implicit2 {
      def main(args: Array[String]): Unit = {
    
        //java.io.File 只封装了文件的元数据,文件内容必须通过IO
        //所以File 后无法直接获取context
        val context:String = new File("").readContext
      }
    
    }
    

    隐式转换更多的应用在此,想要实现File 后 直接获取readContext 必须自己封装这个方法,然后实现隐式转换

    object implicit2 {
      def main(args: Array[String]): Unit = {
        //声明隐式转换
        implicit def file2RichFile(file: File):RichFile = new RichFile(file)
        
    
        //java.io.File 只封装了文件的元数据,文件内容必须通过IO
        //所以File 后无法直接获取context
        val context:String = new File("").readContext
      }
    
    }
    
    class RichFile(file:File){
      //自己封装一个,让File后能readContext
      def readContext:String = {
        Source.fromFile(file).mkString
      }
    }
    

    整理一下这个流程:

    java.io.File 无 readContext方法
    	查找implicit函数
    		传入参数为File , 返回方法当中有没有一个方法为readcontext
    		以上匹配关系必须唯一
    	
    
    implicit def int2Date(int: Int):RichDate = new RichDate(int)
    
        val ago:String = "ago"
        val later:String = "later"
        val day2 = 2.days(ago)
    
    class RichDate(day:Int){
      def days(when : String) = {
        if("ago"==when)
          LocalDate.now().plusDays(-day).toString
        else if("later"==when)
          LocalDate.now().plusDays(day).toString
        else
          println("later or age error")
      }
    }
    

    2.2 隐式类

    在这里插入图片描述
    注意,隐式函数引用的时候,implict 关键字标黄了
    这是啥意思呢?

    这是在说:your code is as same sa the shit

    since Scala2.10

    再一次简化隐式转换,直接把类写在里面即可

    object implicit3 {
      def main(args: Array[String]): Unit = {
    
        val ago : String = "ago"
        val later : String = "later"
    
        println(3.days(later))
    
        implicit class RichDate(day:Int){
          def days(when:String): Unit ={
            if ("ago" == when){
              LocalDate.now().plusDays(-day).toString
            }else if("later" == when){
              LocalDate.now().plusDays(day).toString
            }
          }
        }
      }
    

    隐式类要求
    (1)其所带的构造参数有且只能有一个
    (2)隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是顶级的。

    2.3 隐式解析机制

    之前有一些提到,

    (1)首先会在当前代码作用域下查找隐式实体(隐式方法、隐式类、隐式对象)。(一般是这种情况)
    (2)如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。类型的作用域是指与该类型相关联的全部伴生对象以及该类型所在包的包对象

    三.回归主题

    开头提到 一个 DF.select

      /**
       * :: Experimental ::
       * (Scala-specific) Implicit methods available in Scala for converting
       * common Scala objects into `DataFrame`s.
       *
       * {{{
       *   val sparkSession = SparkSession.builder.getOrCreate()
       *   import sparkSession.implicits._
       * }}}
       *
       * @since 2.0.0
       */
      @Experimental
      @InterfaceStability.Evolving
      object implicits extends SQLImplicits with Serializable {
        protected override def _sqlContext: SQLContext = SparkSession.this.sqlContext
      }
    
      /**
       * Selects a set of column based expressions.
       * {{{
       *   ds.select($"colA", $"colB" + 1)
       * }}}
       *
       * @group untypedrel
       * @since 2.0.0
       */
      @scala.annotation.varargs
      def select(cols: Column*): DataFrame = withPlan {
        Project(cols.map(_.named), logicalPlan)
      }
    

    DF. 没有select
    需要用隐式转换成DS
    然后用ds.select

    展开全文
  • MySQL令人咋舌的隐式转换

    万次阅读 多人点赞 2019-09-19 09:53:13
    避免发生隐式类型转换,隐式转换的类型主要有字段类型不一致、in参数包含多个类型、字符集类型或校对规则不一致等 隐式类型转换可能导致无法使用索引、查询结果不准确等,因此在使用时必须仔细甄别 数字类型的建议在...

    导读

    作者徐晨亮, MySQL DBA,知数堂学员。热衷于数据库优化,自动化运维及数据库周边工具开发,对 MySQL源码有一定的兴趣
    本文建议横屏观看,效果更佳


    一、问题描述

    root@mysqldb 22:12:  [xucl]> show create table t1\G
    *************************** 1. row ***************************
           Table: t1
    Create Table: CREATE TABLE `t1` (
      `id` varchar(255) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    
    root@mysqldb 22:19:  [xucl]> select * from t1;
    +--------------------+
    | id                 |
    +--------------------+
    | 204027026112927605 |
    | 204027026112927603 |
    | 2040270261129276   |
    | 2040270261129275   |
    | 100                |
    | 101                |
    +--------------------+
    6 rows in set (0.00 sec)
    

    奇怪的现象:

    root@mysqldb 22:19:  [xucl]> select * from t1 where id=204027026112927603;
    +--------------------+
    | id                 |
    +--------------------+
    | 204027026112927605 |
    | 204027026112927603 |
    +--------------------+
    2 rows in set (0.00 sec)
    

    640?wx_fmt=jpeg

    什么鬼,明明查的是204027026112927603,为什么204027026112927605也出来了

    二、源码解释

    堆栈调用关系如下所示:

    640?wx_fmt=jpeg

    其中JOIN::exec()是执行的入口,Arg_comparator::compare_real()是进行等值判断的函数,其定义如下

    int Arg_comparator::compare_real()
    {
      /*
        Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
        gcc to flush double values out of 80-bit Intel FPU registers before
        performing the comparison.
      */
      volatile double val1, val2;
      val1= (*a)->val_real();
      if (!(*a)->null_value)
      {
        val2= (*b)->val_real();
        if (!(*b)->null_value)
        {
          if (set_null)
            owner->null_value= 0;
          if (val1 < val2)  return -1;
          if (val1 == val2) return 0;
          return 1;
        }
      }
      if (set_null)
        owner->null_value= 1;
      return -1;
    }
    

    比较步骤如下图所示,逐行读取t1表的id列放入val1,而常量204027026112927603存在于cache中,类型为double类型(2.0402702611292762E+17),所以到这里传值给val2后val2=2.0402702611292762E+17。

    640?wx_fmt=jpeg

    当扫描到第一行时,204027026112927605转成doule的值为2.0402702611292762e17,等式成立,判定为符合条件的行,继续往下扫描,同理204027026112927603也同样符合

    640?wx_fmt=jpeg

    如何检测string类型的数字转成doule类型是否溢出呢?这里经过测试,当数字超过16位以后,转成double类型就已经不准确了,例如20402702611292711会表示成20402702611292712(如图中val1)

    640?wx_fmt=jpeg

    640?wx_fmt=jpeg

    MySQL string转成double的定义函数如下:

    {
      char buf[DTOA_BUFF_SIZE];
      double res;
      DBUG_ASSERT(end != NULL && ((str != NULL && *end != NULL) ||
                                  (str == NULL && *end == NULL)) &&
                  error != NULL);
    
      res= my_strtod_int(str, end, error, buf, sizeof(buf));
      return (*error == 0) ? res : (res < 0 ? -DBL_MAX : DBL_MAX);
    }
    

    真正转换函数my_strtod_int位置在dtoa.c(太复杂了,简单贴个注释吧)

    /*
      strtod for IEEE--arithmetic machines.
     
      This strtod returns a nearest machine number to the input decimal
      string (or sets errno to EOVERFLOW). Ties are broken by the IEEE round-even
      rule.
     
      Inspired loosely by William D. Clinger's paper "How to Read Floating
      Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
     
      Modifications:
     
       1. We only require IEEE (not IEEE double-extended).
       2. We get by with floating-point arithmetic in a case that
         Clinger missed -- when we're computing d * 10^n
         for a small integer d and the integer n is not too
         much larger than 22 (the maximum integer k for which
         we can represent 10^k exactly), we may be able to
         compute (d*10^k) * 10^(e-k) with just one roundoff.
       3. Rather than a bit-at-a-time adjustment of the binary
         result in the hard case, we use floating-point
         arithmetic to determine the adjustment to within
         one bit; only in really hard cases do we need to
         compute a second residual.
       4. Because of 3., we don't need a large table of powers of 10
         for ten-to-e (just some small tables, e.g. of 10^k
         for 0 <= k <= 22).
    */
    

    既然是这样,我们测试下没有溢出的案例

    root@mysqldb 23:30:  [xucl]> select * from t1 where id=2040270261129276;
    +------------------+
    | id               |
    +------------------+
    | 2040270261129276 |
    +------------------+
    1 row in set (0.00 sec)
    
    root@mysqldb 23:30:  [xucl]> select * from t1 where id=101;
    +------+
    | id   |
    +------+
    | 101  |
    +------+
    1 row in set (0.00 sec)
    

    结果符合预期,而在本例中,正确的写法应当是

    root@mysqldb 22:19:  [xucl]> select * from t1 where id='204027026112927603';
    +--------------------+
    | id                 |
    +--------------------+
    | 204027026112927603 |
    +--------------------+
    1 row in set (0.01 sec)
    

    三、结论

    1. 避免发生隐式类型转换,隐式转换的类型主要有字段类型不一致、in参数包含多个类型、字符集类型或校对规则不一致等

    2. 隐式类型转换可能导致无法使用索引、查询结果不准确等,因此在使用时必须仔细甄别

    3. 数字类型的建议在字段定义时就定义为int或者bigint,表关联时关联字段必须保持类型、字符集、校对规则都一致

    4. 最后贴一下官网对于隐式类型转换的说明吧

    1、If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe
    <=> equality comparison operator. For NULL <=> NULL, the result is true. No conversion is needed.
    2、If both arguments in a comparison operation are strings, they are compared as strings.
    3、If both arguments are integers, they are compared as integers.
    4、Hexadecimal values are treated as binary strings if not compared to a number.
    5、If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a
    constant, the constant is converted to a timestamp before the comparison is performed. This is
    done to be more ODBC-friendly. This is not done for the arguments to IN(). To be safe, always
    use complete datetime, date, or time strings when doing comparisons. For example, to achieve best
    results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to
    the desired data type.
    A single-row subquery from a table or tables is not considered a constant. For example, if a subquery
    returns an integer to be compared to a DATETIME value, the comparison is done as two integers.
    The integer is not converted to a temporal value. To compare the operands as DATETIME values,
    use CAST() to explicitly convert the subquery value to DATETIME.
    6、If one of the arguments is a decimal value, comparison depends on the other argument. The
    arguments are compared as decimal values if the other argument is a decimal or integer value, or as
    floating-point values if the other argument is a floating-point value.
    7、In all other cases, the arguments are compared as floating-point (real) numbers.
    

    参考文章

    1、聊聊 隐式转换

    2、Type Conversion in Expression Evaluation:https://dev.mysql.com/doc/refman/8.0/en/type-conversion.html

    感谢八怪的友情指导,想学习更多源码内容,强烈推荐一下八怪的专栏《深入理解MySQL主从原理》

    END


    点击下图小程序订阅

    《深入理解MySQL主从原理32讲》专栏

    可了解更多八怪技术文章

    640?wx_fmt=png

    640?wx_fmt=png

    640?wx_fmt=gif

    扫码加入MySQL技术Q群

    (群号:793818397)

       

    展开全文
  • Scala 隐式转换 重要一点 什么事隐式转换

    Scala 隐式转换 重要一点 什么事隐式转换


    package com.xing.listfile
    
    /**
      * Created by DengNi on 2017/2/12.
      * 简要说明 implicit 是什么 ? 就是从一个类的对象调用另外一个类方法
      */
    //Method 1 OptimusPrime can not call AutoBots 's function BlowFire
    // 增加 OptimusPrime object 对象 实现隐式转换
    class OptimusPrime(val function :String)  //此处 val 是必须的 ,不然找不到 optimusPrime.function
    /**
    object OptimusPrime{
      implicit def optimusPrime2AutoBots(optimusPrime:OptimusPrime) = new AutoBots(optimusPrime.function)
    }
    **/
    class AutoBots(function : String){
      def blowFire = println(function + ": I can blow fire to fire you!!!")
    }
    //Method 2 定义一个不同类名字的 object  对象  ,zai  main 方法里面引用这个 对象
    object implictis {
      implicit def optimusPrime2AutoBots(optimusPrime:OptimusPrime) = new AutoBots(optimusPrime.function)
    }
    
    object HelloImplicit {
    
      def main(args: Array[String]) {
        import implictis._
        val op = new OptimusPrime("OptimusPrime")
        println(op.blowFire)
    
        //多参数
       // talk("p1") 只传一个参数 指定是错的了
        talk("p1")("p22")
    
        // 但是我们就只想传一个 呢??
        implicit val name2 ="eat you"  //此处也引用了 隐式转换
        talk2("p3")
    
    
      }
      // 定义一个函数 有两个参数
      def talk(name1 : String)(name2:String) = println("thera are 2 param")
      def talk2(name1 : String)(implicit name2:String) = println("thera are 2 param " +name2) // 此处 implicit 必须加
    }
    /**
    "C:\Program Files\Java\jdk1.7.0_80\bin\java" -Didea.launcher.port=7532 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_80\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_80\jre\lib\rt.jar;D:\bigdataworkspaces\kafSpSt\out\production\kafSpSt;F:\scala\lib\scala-actors-migration.jar;F:\scala\lib\scala-actors.jar;F:\scala\lib\scala-library.jar;F:\scala\lib\scala-reflect.jar;F:\scala\lib\scala-swing.jar;D:\bigdataworkspaces\kafSpSt\lib\fastjson-1.2.11.jar;D:\bigdataworkspaces\kafSpSt\lib\fastutil-7.0.11.jar;D:\bigdataworkspaces\kafSpSt\lib\kafka_2.10-0.8.2.1.jar;D:\bigdataworkspaces\kafSpSt\lib\mysql-connector-java-5.1.6.jar;D:\bigdataworkspaces\kafSpSt\lib\mysql-connector-java-5.1.8-bin.jar;D:\bigdataworkspaces\kafSpSt\lib\spark-assembly-1.6.0-hadoop2.6.0.jar;D:\bigdataworkspaces\kafSpSt\lib\spark-examples-1.6.0-hadoop2.6.0.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.3\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain com.xing.listfile.HelloImplicit
    OptimusPrime: I can blow fire to fire you!!!
    ()
    thera are 2 param
    thera are 2 param eat you
    
    Process finished with exit code 0
     **/


    展开全文
  • * 隐式转换是Scala中一种特殊的功能,它能将一种数据类型转换成另外一种数据类型, * 然后这种数据类型将拥有另外一种数据类型的所有方法,可以看成是对类的一种增强。 * 隐式转换分为两种: * 1.隐式转换函数 ...
    /**
      * 隐式转换是Scala中一种特殊的功能,它能将一种数据类型转换成另外一种数据类型,
      * 然后这种数据类型将拥有另外一种数据类型的所有方法,可以看成是对类的一种增强。
      * 隐式转换分为两种:
      * 1.隐式转换函数
      * 2.隐式转换值
      *
      * 定义隐式转换的关键字是implicit
      * 隐式转换的命名方式是one2one的形式
      */
    class SpecialPeron(var name: String)
    
    class Older(var name: String)
    
    class Student(var name: String)
    
    class Teach(var name: String)
    
    object ImplicitDemo {
      def buySpecialTickWindow(peron: SpecialPeron): Unit = {
        if (peron != null) {
          println(peron.name + "购买了一张特殊票!")
        } else {
          println("你不是特殊人群,不能在此买票!")
        }
      }
    
      //隐式转换函数
      implicit def any2SpecialPerson(any: Any): SpecialPeron = {
        /**
          * if条件结构
          */
        //    if (any.isInstanceOf[Older]) {
        //      new SpecialPeron(any.asInstanceOf[Older].name)
        //    } else if (any.isInstanceOf[Student]) {
        //      new SpecialPeron(any.asInstanceOf[Student].name)
        //    } else {
        //      null
        //    }
        /**
          * 模式匹配
          */
        any match {
          case any: Older => new SpecialPeron(any.asInstanceOf[Older].name)
          case any: Student => new SpecialPeron(any.asInstanceOf[Student].name)
          case _ => null
        }
      }
    
      def main(args: Array[String]): Unit = {
        val older = new Older("老人")
        val student = new Student("学生")
        val teacher = new Teach("讲师")
    
        buySpecialTickWindow(older)
        buySpecialTickWindow(student)
        buySpecialTickWindow(teacher)
      }
    }
    
    展开全文
  • Scala之隐式转换

    万次阅读 多人点赞 2016-03-12 16:53:41
    概述简单说,隐式转换就是:当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转化提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型。隐式转换有四种常见的使用场景: 将某一类型转换成...
  • 22隐式转换

    2021-01-20 12:16:06
    1.隐式转换 其实就是添加一个关键字[implicit],这种转换是自动执行的,将一种类型转换为另一种类型 //定义隐式类: implicit def m(x:Double) = x.toInt val i:Int = 3.5 2.隐式转换作用 //定义隐式类(可以把File...
  • scala之隐式转换

    千次阅读 2019-05-08 13:01:19
    实现方式:隐式转换函数接收的参数类型定义的对象时,会自动将其传入隐式转换函数 本质:自动的调用你新增的“超级方法” 作用:允许你手动指定,将某种类型的对象转换成其他类型的对象 1、函数隐式转换 结构:...
  • Scala泛型、隐式转换和隐式参数、视图介绍、Scala中的上界、下界、结合柯里化进行隐式转换.pdf
  • 隐式转换就是,让某一个类具有另一个class(或者另一个object)的方法/参数值。 隐式参数&隐式方法 隐式参数,用一个类型的隐式参数只能定义异常 implicit修饰隐式值或者有方法 相应触发隐式转换,需要在使用处...
  • Scala隐式转换

    2019-03-22 23:31:33
    隐式转换:简单的说,隐式转换就是当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转换提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型。 概念:隐式转换和隐式参数是Scala中两个非常...
  • sql隐式转换This article will provide an overview of SQL Server implicit conversion including data type precedence and conversion tables, implicit conversion examples and means to detect occurrences of...
  • Scala 隐式转换

    2019-10-29 20:08:15
    什么是隐式转换 我理解的隐式转换是一种能像装饰器设计模式一样,对原有功能进行增强的语法。 当原有函数不具备某些我们想要的功能时,我们或许可以通过隐式转换来解决这样的问题。 比如我们想得到一杯果汁,却只有...
  • 主要介绍了Java基础之隐式转换vs强制转换的相关资料,需要的朋友可以参考下
  • Scala 隐式转换.pdf

    2021-08-26 15:31:19
    Scala 隐式转换.pdf
  • C# 隐式转换

    2019-08-18 08:22:12
    下面几种类型的转换被称之为隐式转换 同一性转换 隐式数值转换 隐式枚举转换 隐式引用转换 包装转换 隐式常数表达式转换 用户自定义隐式转换 隐式转换可以在很多种情况下发生,包括函数子句调用,cast...
  • scala隐式转换

    千次阅读 2018-09-05 07:25:38
    隐式转换的概念 隐式转换的使用 隐式转换做参数类型转换 隐式转换增强现有类型 隐式参数 利用隐式参数进行隐式转换 再议Context Bounds 隐式转换的概念 隐式转换函数(implicit conversion function)是以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 206,217
精华内容 82,486
关键字:

隐式转换