在Scala函数中按名称调用参数

时间:2019-06-03 13:41:33

标签: scala

我对这两个功能之间的区别有疑问:

def getFunction(checkpointPath: String,
                  sparkConf: SparkConf,
                  creatingFunc: () => StreamingContext): StreamingContext = {
    function body
  }


def getFunction(checkpointPath: String,
                  sparkConf: SparkConf,
                  creatingFunc:  => StreamingContext): StreamingContext = {
    function body
  }

因此,按名称调用的参数是相同的:

creatingFunc:  => StreamingContext 

creatingFunc: () => StreamingContext

还是不?

2 个答案:

答案 0 :(得分:5)

两者不一样。第一种情况指定按名称调用的方法参数

creatingFunc:  => StreamingContext 

在第二种情况下,指定了按值传递方法参数,其中该参数恰好是类型() => StreamingContex的函数

creatingFunc: () => StreamingContext

例如,考虑以下两种方法

def foo(arg: () => String) = ""
def foo(arg: => String) = ""

然后

foo(() => "") // resolves to call first foo
foo("")       // resolves to call second foo

答案 1 :(得分:3)

马里奥的答案是正确的:它们并不相同。但是,它们通常用于完全相同的目的,两者之间的选择通常与语法有关,而不是语义。

例如,您可能想编写一个repeat方法,该方法以两种方式重复给定的代码块:

def repeat1(n: Int)(block: () => Unit): Unit = ???
def repeat2(n: Int)(block: => Unit): Unit = ???

定义几乎相同,但在呼叫站点的用法不同:

repeat1(10) { () => 
    // my awesome code goes here
}

repeat2(10) { 
    // my awesome code goes here
}

在这种情况下,第二种选择感觉自然得多:就像现在while一样,重复似乎是语言的一部分!

在Scala(DSL)中创建特定于域的语言时,广泛使用了这种漂亮的语法。对于其他所有内容,我都希望保持明确,并使用Function0定义,因为这样更容易跟踪确切何时计算值。