我注意到,如果定义这个琐碎的函数,我会得到相同的效果:
12
如果我定义一个变量并为其分配一个lambda(具有相同的主体):
fun double ( i: Int ) = i*2
如果我用任一声明调用var double = { i : Int -> i*2 }
,我将得到相同的结果。
这让我感到困惑。建议何时需要将变量定义为lambda而不是为其定义函数,这是有利的?
答案 0 :(得分:6)
建议何时需要将变量定义为lambda而不是为其定义函数是有利的?
无论何时选择,都应使用fun
声明。即使使用fun
,您仍然可以通过使用函数引用从中获得一流的可调用对象。
在JVM上,无论是在RAM还是在调用开销方面,fun
的重量都明显更轻。它编译成Java方法,而val
编译成实例字段+ getter +实现功能接口的综合类+该类的单例实例,您必须在其上获取,解引用和调用方法
仅当某些事情迫使您这样做时,才应考虑使用函数类型的val
或var
。一个示例是您可以动态替换var
并有效地更改函数的定义。您可能还会从外部接收功能对象,或者可能需要遵循需要它们的API。
无论如何,如果您曾经使用一个类的函数类型的属性,您就会知道为什么要这么做。
答案 1 :(得分:4)
首先,如果我理解正确,您的问题是:“为什么Kotlin中的功能一等公民?为什么要这样使用它们?”,对吗?
Kotlin函数是一流的,这意味着它们可以存储在变量和数据结构中,作为参数传递给其他高阶函数并从其他高阶函数返回。您可以通过其他非函数值可能使用的任何方式来使用函数。 (see here)
如文档中所述,一个用例是高阶函数。第一步,我将在此处保留Wikipedia链接:https://en.wikipedia.org/wiki/Higher-order_function
基本上是高阶函数is a function that takes functions as parameters, or returns a function。 这意味着高阶函数至少具有一个 function type 参数或返回一个 function type 值。
下面是接收函数类型为(Int) -> Boolean
的参数的高阶函数的简短示例:
fun foo(pred: (Int) -> Boolean) : String = if(pred(x)) "SUCCESS" else "FAIL"
现在可以使用任何(Int) -> Boolean
函数来调用此高阶函数。
文档还声明 ... [可以用于]其他非功能值。
例如,这意味着您可以根据当前上下文为变量分配不同的功能。
例如:
// This example is verbose on purpose ;)
var checker: (Int) -> Boolean
if (POSITIVE_CHECK) {
checker = { x -> x > 0 } // Either store this function ...
} else {
checker = { x -> x < 0 } // ... or this one ...
}
if (checker(someNumber)) { // ... and use whatever function is now stored in variable "checker" here
print("Check was fine")
}
(未经测试的代码)
答案 2 :(得分:2)
由于某些原因想要更改行为时,可以定义变量并将其分配为lambda。例如,在几种情况下,您有不同的公式。
val formula: (Int) -> Int = when(value) {
CONDITION1 -> { it*2 }
CONDITION2 -> { it*3 }
else -> { it }
}
val x: Int = TODO()
val result = formula(x)
如果仅需要帮助程序功能,则应将其定义为fun
。
答案 3 :(得分:1)
如果将lambda作为函数的参数传递,它将存储在变量中。调用应用程序可能需要保存该内容(例如事件监听器,以备后用)。因此,您还需要能够将其存储为变量。如答案中所述,仅应在需要时执行此操作!
答案 4 :(得分:0)
对我来说,我会按如下方式编写 Lambda 变量:
var double: (Int) -> Int = { i -> //no need to specify parameter name in () but in {}
i*2
}
这样你就可以很容易地知道它的类型是(i: Int) -> Int
,读作takes an integer and returns an integer
。
然后你可以把它传递给某个地方,比如一个函数:
fun doSomething(double: (Int) -> Int) {
double(i)
}