2015-01-08 64 views
1

我對面,看起來像這樣的函數跑:斯卡拉無參數字符串函數VS輸入字符串參數

def doSomethingQuestionable(config: someConfig, value: String)(default: => String) : String 

什麼是有趣的是,被作爲第二個參數組傳入的參數的功能。在代碼庫中,該方法只用一個配置和兩個字符串調用,後者是一些默認值,但是作爲一個字符串,而不是函數。在該方法的代碼體內,缺省值被傳遞給一個需要3個字符串參數的方法。所以函數「default」只能解析爲這個方法體內的一個字符串。

除了在我正在經歷的代碼庫中用這種方法沒有發生的currying用法之外,是否有任何好處以這種方式定義方法?爲什麼不在單個參數組中使用3個字符串參數進行定義?

我錯過了什麼?這裏有一些編譯器優勢請記住,我假設不會用這種方法來進行卷曲,因爲它是一個很大的代碼庫,而且目前還沒有用這種方法完成。

+0

拆分參數到2只列出了允許在某些特定情況下,類型推斷:http://stackoverflow.com/questions/13868085/ – Infinity

+0

'default'是一個「調用 - 名」參數。它是懶惰的功能評估(或根本不需要)。 – Ryan

+0

人們喜歡的語法:'f(a,b){val s =「hi」; s}'。 http://www.artima.com/pins1ed/control-abstraction.html#9.4 –

回答

2

重點是有一個潛在的昂貴的默認字符串,只有當你需要它時纔會創建。你編寫代碼就好像你正在創建要傳入的字符串一樣,但是因爲它是一個名字參數('=> String'),它實際上會變成一個函數,在函數default被引用時,它將被透明地調用doSomethingQuestionable方法。

如果你想要一大塊代碼來創建該字符串,保持它分開的理由。如果你從來沒有做,永遠不會,它也可以被

def doSomethingQuestionable(config: someConfig, value: String, default: => String): String 

如果你這樣做,但是,

def doSomethingQuestionable(cfg, v){ 
    // Oh boy, something went wrong 
    // First we need to check if we have a database accessible 
    ... 
    // (Much pain ensues) 
    result 
} 

的方式比在多參數參數中嵌入的代碼塊作爲一個參數更好名單。

1

這是一個無參數的函數返回一個String

() => String 

這是不是你有什麼。

=> <WHATEVER> 

是通過名字,而不是按值被傳遞的參數。例如:

=> String // A string being passed by-name 
=>() => String // A parameterless function returning string being passed by-name 

這些模式之間的差別在於,在由值,該參數是評價被傳遞,而在按名稱,參數被傳遞「所得到的是「,並在每次使用時進行評估。

例如:

var x = 0 
def printValue(y: Int) = println(s"I got $y. Repeating: $y.") 
def printName(y: => Int) = println(s"I got $y. Repeating: $y.") 

printValue { x += 1; x } // I got 1. Repeating: 1. 
printName { x += 1; x } // I got 2. Repeating: 3. 

現在,至於爲什麼該方法是分割成第二個參數,它只是一個語法愉快的事情。例如,採用類似定義的方法foldLeft。你可以寫這樣的事情:

(1 to 10).foldLeft(0) { (acc, x) => 
    println(s"Accumulator: $acc\tx: $x\tacc+x: ${acc+x}") 
    acc+x 
} 

如果foldLeft被定義爲一個單一的參數列表,它應該是這樣的:

(1 to 10).foldLeft(0, { (acc, x) => 
    println(s"Accumulator: $acc\tx: $x\tacc+x: ${acc+x}") 
    acc+x 
}) 

沒有太大的不同,理所當然,但更糟糕的期待。我的意思是,你不會在下面寫這個東西,是嗎?

if (x == y, { 
    println("Same thing") 
}, { 
    println("Different thing" 
})