2015-10-06 60 views
0

在一個Scala類中,目標是實現一個Builder模式,並且構造類的參數之一是一個函數,它接收一個元組並且返回一個Double。在Scala中,如何使用元組參數定義一個函數變量

在Builder類中,變量tupleFunc需要用默認實現來保存此類型的函數。 Builder還會有一個方法tupleFuncIs覆蓋默認值。

class FunctionProblem private (val tupleFunc: (Boolean, Double, Int) => Double, 
           val func: Double => Double) { 

} 

object FunctionProblem { 
    class Builder { 
    // problem line follows 
    private var tupleFunc: ((Boolean, Double, Int) => Double) = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble 
    private var func: (Double => Double) = (x: Double) => 0.75 * x 

    def tupleFuncIs(x: (Boolean, Double, Int) => Double): Builder = { tupleFunc = x; this } 
    def funcIs(x: Double => Double): Builder = { func = x; this } 

    def build(): FunctionProblem = new FunctionProblem(tupleFunc, func) 
    } 

    def builder(): Builder = new Builder 
} 

然而,Scala編譯器抱怨類型不匹配的

[ant:scalac] found : ((Boolean, Double, Int)) => Double 
[ant:scalac] required: (Boolean, Double, Int) => Double 
[ant:scalac]  private var tupleFunc: ((Boolean, Double, Int) => Double) = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble 
[ant:scalac]                       ^

爲什麼有發現,雙括號或更好,但應該如何tupleFunc被改寫,以滿足編譯器?

回答

3

你需要更多的括號

class FunctionProblem private (val tupleFunc: ((Boolean, Double, Int)) => Double, 
    val func: Double => Double) { 

} 

object FunctionProblem { 
    class Builder { 
    // problem line follows 
    private var tupleFunc: ((Boolean, Double, Int)) => Double = (x: (Boolean, Double, Int)) => if (x._1) x._2 else x._3.toDouble 
    private var func: (Double => Double) = (x: Double) => 0.75 * x 

    def tupleFuncIs(x: ((Boolean, Double, Int)) => Double): Builder = { tupleFunc = x; this } 
    def funcIs(x: Double => Double): Builder = { func = x; this } 

    def build(): FunctionProblem = new FunctionProblem(tupleFunc, func) 
    } 

    def builder(): Builder = new Builder 
} 

這裏

((Boolean, Double, Int) => Double) 

你的類型是一個簡單的函數,有3個參數不是一個元組,對元組需要將其包裝在一個更()這樣:

(((Boolean, Double, Int)) => Double) 

順便說一句,儘管你的代碼中有函數不是ve ry功能性,它看起來很像java。你也許應該考慮使用不可變的值,並在中立時返回新的構建器。

我的建議,以實現更多的Scala方式這個任務是使用case class

import FunctionProblem._ 

case class FunctionProblem(tupleFunc: TupleFunc = defaultTupleFunc, func: DoubleFunc = defaultDoubleFunc) 

object FunctionProblem { 
    type TupleFunc = ((Boolean, Double, Int)) => Double 
    type DoubleFunc = Double => Double 

    private val defaultTupleFunc: TupleFunc = x => if (x._1) x._2 else x._3.toDouble 
    private val defaultDoubleFunc: DoubleFunc = 0.75 * _ 
} 

FunctionProblem().func(3) //res0: Double = 2.25 
FunctionProblem(func = _ + 5).func(3) //res1: Double = 8.0 
FunctionProblem(tupleFunc = _ => 32).tupleFunc((true, 5, 1)) //res2: Double = 32.0 

如果你想,你可以使用自動生成的copy方法

FunctionProblem().copy(func = _ + 9).copy(tupleFunc = _ => 3).func(1) //res3: Double = 10.0 
到鏈通話
相關問題