【问题标题】:Understanding Scala implicit conversion and generic type inference理解 Scala 隐式转换和泛型类型推断
【发布时间】:2015-06-23 22:04:00
【问题描述】:
trait LowPriorityOrderingImplicits {
  implicit def ordered[A <: Ordered[A]]: Ordering[A] = new Ordering[A] {
    def compare(x: A, y: A) = x.compare(y)
  }
}

上面的代码是做什么的?

  1. A <: ordered a>
  2. “new Ordering[A]{...”究竟是做什么的?它是否为 Ordering[A] 创建了一个新的匿名类?

另外,对于这段代码(取自DataStax Cassandra Connector)

        object TableWriter{
          def apply[T : RowWriterFactory](
          connector: CassandraConnector,
          keyspaceName: String,
          tableName: String,
          columnNames: ColumnSelector,
          writeConf: WriteConf): TableWriter[T] = {
            ...//some code
            val rowWriter = implicitly[RowWriterFactory[T]].rowWriter(tableDef, selectedColumns)
            new TableWriter[T](connector, tableDef, rowWriter, writeConf)
          }
        }
        val writer = TableWriter(connector, keyspaceName, tableName, columns, writeConf) // first call

        def saveToCassandra(keyspaceName: String,
                          tableName: String,
                          columns: ColumnSelector = AllColumns,
                          writeConf: WriteConf = WriteConf.fromSparkConf(sparkContext.getConf))
                         (implicit connector: CassandraConnector = CassandraConnector(sparkContext.getConf),
                          rwf: RowWriterFactory[T]): Unit = {
             val writer = TableWriter(connector, keyspaceName, tableName, columns, writeConf)// 2nd call
        }
  1. 如何推断 T 的类型?
  2. rwf 隐式参数的目的是什么?
  3. 第一次和第二次调用 TableWriter 有什么区别?

【问题讨论】:

    标签: scala


    【解决方案1】:

    A <: ordered a>

    我们来看看Ordered的定义:

    trait Ordered[A] extends Any with java.lang.Comparable[A] {
    
      def compare(that: A): Int
    
      /* ... */
    }
    

    如果我们说A &lt;: Ordered[A],那么我们指定A 的实例与A 的其他实例相当。为什么在给定的情况下这是必要的?嗯...说我们有

    implicit def ordered[B, A <: Ordered[B]]: Ordering[A] = new Ordering[A] {
      def compare(x: A, y: A) = x.compare(y)
    }
    

    这段代码不会编译,因为Ordered[B] 没有方法compare(x: A)(注意y 的类型是A)。

    “new Ordering[A]{...”究竟是做什么的?它是否为 Ordering[A] 创建了一个新的匿名类?

    是的,这是一个匿名类。

    如何推断 T 的类型?

    T: RowWriterFactory 是上下文绑定的。另请参阅Scala doc about type tags and manifests。

    据我所知,

    def foo[T: RowWriterFactory](x: Int) 
    

    和写法一样

    def foo[T](x: Int)(implicit evidence: RowWriterFactory[T])
    

    rwf 隐式参数的作用是什么?

    这来自上一个问题的答案:它是上下文绑定的。虽然我不知道这个特定示例中的用法。 编辑 由于TableWriter 的apply 方法需要通过上下文绑定RowWriterFactory,所以rfw 的目的是用作TableWriter.apply 的隐式参数。

    第一次和第二次调用 TableWriter 有什么区别?

    在不知道第一次调用的参数的情况下,它们是相同的,不是吗?

    【讨论】:

    • 感谢您的详细回复!
    • 1) A <: ordered a scala>
    • 2) 我仍然不明白 T 是如何推断的?就像编译器如何知道要执行什么隐式转换? rwf 的参数化类型是什么?
    • 3) rwf 的目的.... 是什么阻止了 saveToCassandra 在没有上下文绑定的情况下调用 TableWriter.apply? (就像我在第一个 TableWriter 调用中所做的那样)。当我测试代码时,两个 TableWriter 调用得到了不同的结果——我认为这是因为上下文绑定的解析方式不同。不知道为什么
    猜你喜欢
    • 2020-10-12
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 2010-12-20
    • 2018-06-29
    • 2018-11-21
    相关资源
    最近更新 更多