2017-08-13 43 views
4

當編譯這個片段,Scala編譯器將發出以下警告的ETA擴展:零參數法值的編譯時棄用警告:零參數方法

ETA-膨脹已棄用。你有沒有 打算寫Main.this.porFiles5()? [警告] timerFunc(porFiles5)

它發生時,我將一個功能傳遞給另一個簡單的時間。定時器功能採用無參數功能返回單元,在此行:timerFunc(porFiles5)。這個警告是否必要?避免它的慣用方法是什麼?

package example 
import java.nio.file._ 
import scala.collection.JavaConverters._ 
import java.time._ 
import scala.collection.immutable._ 

object Main extends App { 

    val dir = FileSystems.getDefault.getPath("C:\\tmp\\testExtract") 

    def timerFunc (func:()=>Unit) = { 
    val start = System.currentTimeMillis() 
    timeNow() 
    func() 
    val finish = System.currentTimeMillis() 
    timeNow() 
    println((finish - start)/1000.0 + " secs.") 
    println("==================") 
    } 

    def porFiles5(): Unit = { 
    val porFiles5 = Files.walk(dir).count() 
    println(s"You have $porFiles5 por5 files.") 
    } 

    def timeNow(): Unit = { 
    println(LocalTime.now) 
    } 

    timeNow() 
    timerFunc(porFiles5) 
    timeNow() 

} 
+2

FWIW我會建議改變'timerFunc'只取一個名字參數例如'=>單位'。它可以根據需要延遲參數的執行,並很好地迴避了在函數中明確包裝某些東西的需要。 – badcook

+0

@badcook thx。你的意思是這樣(只是爲了確認):'timerFunc2(func:=> Unit):Unit {...}'? – s952163

+1

沒錯,雖然'func'不再是個好名字:) – badcook

回答

9

porFiles5的功能。這是一個方法,這在Scala中完全不同。

如果你有一個方法,但你需要一個功能,您可以使用η膨脹解除方法到一個函數,就像這樣:

someList.foreach(println _) 

斯卡拉會在某些情況下,還進行η自動-expansion,如果是從上下文中絕對清楚你的意思,如:

someList.foreach(println) 

然而,有一個無參數方法的不確定性,因爲Scala允許你調用參數的方法,不帶參數列表,即方法用定義爲空參數列表可以稱爲不帶任何參數列表中的所有:

def foo() = ??? 
foo // normally, you would have to say foo() 

現在,在你的情況下,有歧義:你的意思是呼叫porFiles5或你的意思η-擴大呢?目前,Scala可以任意地消除這種情況並執行η-擴展,但是在將來的版本中,這將是一個錯誤,您將不得不明確執行η-擴展。

所以,擺脫了警告,只需使用顯式η膨脹,而不是隱η膨脹:

timerFunc(porFiles5 _) 
+0

啊,我明白了。當然,當我無法傳入porfiles5()(我的F#背景通過)時,我有點惱怒。所以我想這是一個函數:'val porFiles6 =()=> val porFiles6 = Files.walk(dir).count() println(s「You have $ porFiles6 por6 files。」) }'。 – s952163