2017-08-12 63 views
0

我正在學習用Scala嵌套函數,在這裏的定義是參考向前延伸的價值

object Main extends App { 
    val fac = (x: Int) => { 
     val factorial: (Int, Int) => Int = (x, accum) => if (x == 1) accum else factorial(x-1, accum*x) 
     factorial(x,1) 
    } 

    println(fac(3)) 
} 

編譯一些代碼,我無法給出這樣的錯誤:

forward reference extends over definition of value factorial

val factorial: (Int, Int) => Int = (x, accum) => if (x == 1) accum else factorial(x-1, accum*x)**

什麼我做錯了嗎?

回答

1

你應該申報factorial使用def而不是val

  • 使用val意味着它是一個,評估一次,在申報;因此,很容易看到爲什麼編譯器不能使用這個定義在評估它
  • 使用def意味着它是一個方法,在每次調用單獨評估,因此配套的定義中引用本身(遞歸)

也許混淆的更低的方式來寫,這將是宣佈該方法爲預計參數的方法,而不是它返回期望這些參數的功能的方法:

val fac = (x: Int) => { 
    def factorial(x: Int, accum: Int): Int = if (x == 1) accum else factorial(x-1, accum*x) 
    factorial(x,1) 
} 
+0

什麼時候應該在方法上使用某個函數? – wannabe

+0

方法可以是通用的,函數不能。方法可以有多個參數列表(或沒有),函數總是隻有一個。方法有名字,功能不要。方法可以有重複的參數,功能不能。方法可以有可選參數,功能不可以。方法可以有隱式參數列表,函數不能。所以,如果方法可以做很多功能不能做的事情,爲什麼你會想要使用一個函數呢?那麼,有一件非常重要的事情:功能是對象,方法不是。而且由於Scala是面向對象的語言,你只能用對象做事情。你... –

+0

...不能傳遞一個方法作爲參數,你不能返回一個方法,你不能將一個方法分配給一個變量,你不能在數據結構中存儲一個方法。你只能用對象來做到這一點。 –