2015-09-28 95 views
1

在斯卡拉我發生了一些奇怪的事情。我想使用一個第三方庫沒有ClassTag可用(斯卡拉)

org.apache.spark.streaming.kafka.KafkaUtils.createDirectStream

,並沒有得到ClassTag例外。我模擬下面的場景,因爲人們可以將Util用作第三方庫。這是爲什麼發生?

object Util { 
    def fun1[K: ClassTag, M: ClassTag, KD: ClassTag, MD: ClassTag]: Unit = { 
     println("In function version 2") 
    } 
} 

class ClassTagIssue[K, M, KD, MD] { 
    def build: Unit = { 
     Util.fun1[K, M, KD, MD] 
    } 
} 

object ClassTagIssue { 
    def main(args: Array[String]) { 
     new ClassTagIssue[String, String, String, String]().build 
    } 
} 

我試圖運行該代碼,並獲得異常

Error:(23, 14) No ClassTag available for K 
    Util.fun1[K, M, KD, MD] 
      ^
Error:(23, 14) not enough arguments for method fun1: (implicit evidence$1: scala.reflect.ClassTag[K], implicit evidence$2: scala.reflect.ClassTag[M], implicit evidence$3: scala.reflect.ClassTag[KD], implicit evidence$4: scala.reflect.ClassTag[MD])Unit. 
Unspecified value parameters evidence$1, evidence$2, evidence$3, ... 
    Util.fun1[K, M, KD, MD] 
      ^

回答

5

下面你必須將ClassTag類添加爲綁定到泛型類型的ClassTagIssue的上下文。這樣,您告訴編譯器,K, M, KDMD類型的ClassTags將在創建ClassTagIssue實例時可用。

class ClassTagIssue[K: ClassTag, M: ClassTag, KD: ClassTag, MD: ClassTag] { 
    def build: Unit = { 
    Util.fun1[K, M, KD, MD] 
    } 
} 
+0

由於直到它的工作..這將是巨大的,如果你能解釋一下什麼是問題... –

+0

的問題是,'Util.fun1'預計隱含值的類型'ClassTag [K]',調用範圍內的'ClassTag [M]','ClassTag [KD]'和'ClassTag [MD]'。然而,由於具體類型'K,M,KD'和'MD'是未知的,因此編譯器不能生成它們並且必須由調用者在'ClassTagIssue'範圍內傳遞,因此在'建立'方法。通過將上下文範圍添加到「ClassTagIssue」的通用參數,這是有效的。無論何時創建一個'ClassTagIssue'實例,您還必須爲這些類型提供'ClassTag'實例。 –