2016-04-09 17 views
0

Ben bir özellik bunu beğendi yazarken:Scala'da, vaka sınıfını genişletmek için jenerikler nasıl atanır?

trait Extractor[T] { 

    def parse(sc: SparkContext, path: String): RDD[T] 

    def extract(sc: SparkContext, path: String, output: String): Unit = { 
     val rdd = parse(sc, path) 
     val sqlContext = new HiveContext(sc) 
     import sqlContext.implicits._ 
     SaveUtil.saveAsOrc(rdd.toDF(), output) // error 
    } 
} 

Ben bir vaka sınıfına jenerik T tayin istiyorum:

case class X(uid: String, app: String, tag: String) 

case class Y(uid: String, dvc: String, tag: String) 

Ben scala için bir acemi değilim. Gizli dönüşüm ve kovaryant çalışmaz gibi görünmüyor. Nasıl?

cevap

1

RDD.toDF() bir DataFrameHolder içine örtülü bir dönüşüm sayesinde mevcuttur. Bu dönüşüm, aşağıdaki imzası ile bir method yapılır: Yani

implicit def rddToDataFrameHolder[A <: Product : TypeTag](rdd: RDD[A]): DataFrameHolder 

- Dönüşüm çalışması için:

  • T tüm davanın süper sınıftır Product bir alt sınıfı, olmalı sınıfları (ve Tuples, ve daha fazlası ..).
  • Arayan T (tip silinmesini aşmak için)

Yani türü için örtülü TypeTag olmalıdır - aşağıdaki gibi temelde özelliğin ilanını değiştirmek isterdim: Ancak

// won't work... 
trait Extractor[T <: Product : TypeTag] { /* unchanged */ } 

, özellikler bağlam/görünüm sınırları olan türlere sahip olamaz, bu nedenle bu bildirim çalışmaz.

  1. bir sınıf içine özelliği değiştirin (soyut olabilir) ve bir TypeTag eklemek

    :

    trait Extractor[T <: Product] { 
    
        def parse(sc: SparkContext, path: String): RDD[T] 
    
        def extract(sc: SparkContext, path: String, output: String)(implicit evidence: TypeTag[T]): Unit = { /* unchanged */ } 
    } 
    
    :

    abstract class Extractor[T <: Product : TypeTag] { /* unchanged */ } 
    
  2. extract yöntemine örtük bir argüman ekleyin Burada iki seçeneğiniz var

+0

Teşekkürler @Tzach Zohar çok! Bu problem mükemmel bir şekilde çözüldü! – jyzheng

+0

Bilmekte fayda var, lütfen gelecekteki okuyucuların kolayca bulabilmesi için cevabı + kabul edin –

0
object ExtractorX extends Extractor[X] { 
    override parse(sc: SparkContext, path: String): RDD[X] = ... 
} 

veya

val extractorX = new Extractor[X] { 
    override parse(sc: SparkContext, path: String): RDD[X] = ... 
} 
+0

'extract 'kod bloğunu yeniden kullanmak istiyorum, ancak' toDF() 'yöntemi yalnızca RDD'ye uygulanabilir [vaka sınıfı]. Yani 'SaveUtil.saveAsOrc (rdd.toDF(), çıktı)' derlenmiş bir zamanda bir hata var. – jyzheng

İlgili konular