2015-07-02 25 views
0

我想寫一個函數,它應該根據輸入返回不同的對。我已經覆蓋了Scala中的「+ -/*」以供我特定的使用。每一個(+, - ,*,/)都有三個基於輸入的實現。我有RDD和Float作爲輸入,因此它可以是RDD和RDD之間的+,或Float和RDD,或者Float和Float等。如何在Scala中爲函數分配不同的返回類型?

現在我有一個解析器,它從輸入讀取表達式,如:RDD + 1,解析它並創建後綴,使計算變得更簡單,如:RDD1 +,然後我想用我實現的+進行計算。在this algorithm的幫助下,我試圖改變它的方式,使其根據我的輸入表達式進行計算。例如,它包含:

var lastOp: (Float, Float) => Float = add 

我怎樣才能改變這一點:(Float, Float) => Float的東西,將接受(RDD, Float)|(RDD, RDD) |(Float, Float) => RDD = add //我實現附加的???

版:

我加入這部分有以下兩個答案的幫助: 好,我寫了這個:

 def lastop:(Either[RDD[(Int,Array[Float])], Float], Either[RDD[(Int,Array[Float])], Float]) => RDD[(Int,Array[Float])] = sv.+ 

其中SV是從我的其他類的實例,我一直覆蓋在但在兩種不同的方式所以現在我是個讓我猜的錯誤+是因爲編譯器會很困惑,要使用哪種實現,這是

 error: type mismatch; 
     [error] found : (that: org.apache.spark.rdd.RDD[(Int, Array[Float])])org.apache.spark.rdd.RDD[(Int, Array[Float])] <and> (that: Float)org.apache.spark.rdd.RDD[(Int, Array[Float])] 
     [error] required: (Either[org.apache.spark.rdd.RDD[(Int, Array[Float])],Float], Either[org.apache.spark.rdd.RDD[(Int, Array[Float])],Float]) => org.apache.spark.rdd.RDD[(Int, Array[Float])] 

注意:它發現它是兩個不同的實現「+」

+0

您可以使用函數重載?也就是說,用不同的參數類型來實現這些方法中的每一個。 – marios

+1

afaik,爲了這個工作,你必須以相同的方式實現你的'add'函數。所以你將只有一個使用Either的實現,而不是幾個重載的實現。不過,我會用第三個選項更新我的答案,希望能夠更好地滿足您的需求。 –

+1

對不起,對於第三種選擇,我正在考慮數字[T],現在我認爲它是行不通的。但是,我更新了我的答案,我認爲可能會發揮作用。我不認爲你描述的內容完全可能與你描述的一樣。 –

回答

1

嗯,我不確定這是做到這一點的最佳方式,但它是一種方法來做到這一點,並應導致使用你描述(或至少接近它):

import scala.language.implicitConversions 

// implicit conversions 
implicit def float2Either(in: Float): Either[Float, RDD[(Int,Array[Float])]] = Left(in) 
implicit def rdd2Either(in: RDD[(Int,Array[Float])]): Either[Float, RDD[(Int,Array[Float])]] = Right(in) 

def add(left: Either[Float, RDD[(Int,Array[Float])]], right: Either[Float, RDD[(Int,Array[Float])]]): Float = { 
    (left, right) match { 
    case (Left(someFloat), Left(anotherFloat)) => ??? 
    case (Left(someFloat), Right(someRdd)) => ??? 
    case (Right(someRdd), Left(someFloat)) => ??? 
    case (Right(someRdd), Right(anotherRdd)) => ??? 
    } 
} 
val lastOp: (Either[Float, RDD[(Int,Array[Float])]], Either[Float, RDD[(Int,Array[Float])]]) => Float = add 

另一種方式,可能是更好的一個,將是皮條客我的圖書館模式。

但是,你不能自己決定什麼(浮動+浮動)會產生。最理智的情況下哪一個應該不成問題。

您可以爲Float和RDD編寫隱式包裝類,就像'RichFloat''RichInt'等一樣。爲每個接受另一個作爲輸入的實施運營商。

implicit class RichRdd(val underlying: RDD) extends AnyVal { 
    def +(in: Float): Float = ??? 
    def +(in: Test): Float = ??? 
} 
implicit class RicherFloat(val underlying: Float) extends AnyVal { 
    def +(in: RDD): Float = ??? 
} 
+0

謝謝你幫助我。我有一些問題,什麼是lFloat和rFloat,通過測試你的意思是RDD在我的程序中?那麼什麼是測試和測試? – Rubbic

+1

這是模式匹配,使用提取器(左,右)將所包含的值綁定到新的本地值。你應該查找模式匹配和提取器 –

+0

我有一個問題跟在這裏我們的討論,你能幫我一下嗎? – Rubbic

1

我覺得pattern matching是去,你可能需要做各地的運算符重載更多的研究,以正確的方式。

關於RDD,它應該是一個在Spark中的collection of elements,我不知道你想通過給一個數字添加一個列表來實現什麼,RDD中只有一個元素? ..等等。

不正是你想要知道,這裏用一個例子你怎麼能處理的使用模式匹配類型的不同組合:

import math.hypot 

object test { 

    def myadd(x: Any, y: Any) = (x, y) match { 
     case (x: String, y:String) => x.toInt + y.toInt 
     case (x: String, y:Int) => x.toInt + y.toInt 
     case (x: Int, y:String) => x + y.toInt 
     case (x: Int, y:Int) => x + y 
     case _ => 
    }           //> myadd: (x: Any, y: Any)AnyVal 

    var result = myadd(1,2)     //> result : AnyVal = 3 
    println(result)       //> 3 
    println(result.getClass())    //> class java.lang.Integer 

    result = myadd(1,"2") 
    println(result)       //> 3 
    println(result.getClass())    //> class java.lang.Integer 

    result = myadd(1.0,2) 
    println(result)       //>() 
    println(result.getClass())    //> class scala.runtime.BoxedUnit 

} 
+0

@B。先生W.我已經把任何在myadd類,但它給與錯誤,因爲我發送RDD,它要求任何!不知道爲什麼Any不能接受RDD類型 – Rubbic

相關問題