简体   繁体   中英

Understanding Scala implicit conversion and generic type inference

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

What does the above code do?

  1. What does A <: Ordered[A] mean? How can A be a subtype of Ordered[A]?
  2. What exactly does "new Ordering[A]{..." do? Does it create a new anonymous class for Ordering[A]?

Also, for this code (taken from the 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. How does the type of T get inferred?
  2. What's the purpose of rwf implicit param?
  3. What's the difference between the first and second calls to TableWriter?

What does A <: Ordered[A] mean? How can A be a subtype of Ordered[A]?

Let's look at the definition of Ordered :

trait Ordered[A] extends Any with java.lang.Comparable[A] {

  def compare(that: A): Int

  /* ... */
}

If we say that A <: Ordered[A] , then we specify that instances of A are comparable to other instances of A . Why is this necessary in the given case? Well... say we have

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

This code won't compile, because Ordered[B] has no method compare(x: A) (note that y is of type A ).

What exactly does "new Ordering[A]{..." do? Does it create a new anonymous class for Ordering[A]?

Yes, this is an anonymous class.

How does the type of T get inferred?

T: RowWriterFactory is a context-bound. See also the Scala doc about type tags and manifests .

As far as I know,

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

is the same as writing

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

What's the purpose of rwf implicit param?

This follows from the answer to the previous question: It's the context bound. Though I do not know the usage in this particular example. Edit As the apply -method of TableWriter requires the RowWriterFactory through the context bound, the purpose of rfw is to be used as implicit parameter to TableWriter.apply .

What's the difference between the first and second calls to TableWriter?

Without knowing the arguments to the first call, they are identical, aren't they?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM