Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function lambda分配给Kotlin中的变量。为什么?_Function_Variables_Lambda_Kotlin - Fatal编程技术网

Function lambda分配给Kotlin中的变量。为什么?

Function lambda分配给Kotlin中的变量。为什么?,function,variables,lambda,kotlin,Function,Variables,Lambda,Kotlin,我注意到,如果我定义这个平凡的函数,我会得到同样的效果: fun double ( i: Int ) = i*2 如果我定义了一个变量并给它分配了一个lambda(具有相同的主体): 如果使用两种声明调用double(a),则得到相同的结果。 这让我感到困惑。当需要时,建议将变量定义为lambda而不是为其定义函数,这样做比较有利?当您出于某种原因想要更改行为时,可以定义变量并将其分配为lambda。例如,对于几种情况,您有不同的公式 val formula: (Int) -> Int

我注意到,如果我定义这个平凡的函数,我会得到同样的效果:

fun double ( i: Int ) = i*2
如果我定义了一个变量并给它分配了一个lambda(具有相同的主体):

如果使用两种声明调用
double(a)
,则得到相同的结果。
这让我感到困惑。当需要时,建议将变量定义为lambda而不是为其定义函数,这样做比较有利?

当您出于某种原因想要更改行为时,可以定义变量并将其分配为lambda。例如,对于几种情况,您有不同的公式

val formula: (Int) -> Int = when(value) {
    CONDITION1 -> { it*2 }
    CONDITION2 -> { it*3 }
    else -> { it }
}
val x: Int = TODO() 
val result = formula(x)

如果您只是需要helper函数,您应该首先将其定义为
fun

,如果我没弄错的话,您的问题是“为什么函数是Kotlin的头等公民——以及何时使用它们?”,对吗

Kotlin函数是一级函数,这意味着它们可以存储在变量和数据结构中,作为参数传递给其他高阶函数并从中返回。您可以以其他非函数值可能的任何方式操作函数。()


如文档中所述,一个用例是高阶函数。作为第一步,我将把维基百科链接留在这里:

基本上是一个高阶函数。 这意味着高阶函数至少有一个函数类型的参数或返回函数类型的值

下面是接收函数类型为
(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")
}
//此示例故意冗长;)
变量检查器:(Int)->布尔值
如果(阳性检查){
checker={x->x>0}//存储此函数。。。
}否则{
棋盘格={x->x<0}/…或此棋盘格。。。
}
if(checker(someNumber)){//…并使用现在存储在变量“checker”中的任何函数
打印(“支票没问题”)
}
(代码未经测试)

什么时候需要(建议)将变量定义为lambda而不是为其定义函数

无论何时您可以选择其中一种,都应该使用
fun
声明。即使使用
fun
,您仍然可以通过使用函数引用从中获取一流的可调用对象

在JVM上,
fun
在RAM和调用开销方面都要轻得多。它编译成一个Java方法,而
val
编译成一个实例字段+getter+一个实现函数接口的合成类+一个必须获取、取消引用和调用该类上的方法的该类的单例实例

<>你应该考虑函数类型<代码> Val<代码> >或代码> var >代码>只有当某个东西强迫你去做它时。例如,您可以动态替换
var
,并有效地更改函数的定义。您也可以从外部接收函数对象,或者您可能需要遵守需要它们的API


在任何情况下,如果您使用类的函数类型属性,您都会知道为什么要这样做。

如果您将lambda作为函数的参数传递,它将存储在变量中。调用应用程序可能需要保存该文件(例如,事件侦听器以供以后使用)。因此,您还需要能够将其存储为变量。然而,正如回答中所说,您应该只在需要时才这样做

对于我来说,我将按如下方式编写Lambda变量:

var double: (Int) -> Int = { i ->    //no need to specify parameter name in () but in {}
    i*2 
}
这样您就可以很容易地知道它的类型是
(i:Int)->Int
,读作
接受一个整数并返回一个整数

然后你可以把它传递到某个地方,比如说一个函数:

fun doSomething(double: (Int) -> Int) {
    double(i)
}

在你提到的情况下,我认为最明显的区别是,你可以给lambda任何体,但是你不能改变函数的体。这基本上是一个什么是lambda的问题,不是吗?我不明白你的问题。你在比较一个函数和一个变量。显然,它们都有各自的用途。其中一个用途是在内联函数中使用它们。他的var-double和fun-double在幕后是否完全相同?是否只是语法将它们区分开来?@Adam:不,一般来说,a
fun
更轻量级。(另见@Marko Topolnik的答案)。只是一个简单的解释:a
val
var
是堆上的一个对象,即占用内存,函数类型的变量也是如此。A
fun
是一个函数,是存储在JVM内部的类描述的一部分。谢谢。我正在学习关于Udacity的“Kotlin训练营”课程,它提出了这个例子,但没有真正进入这些“细节”。非常有用。回答得很好,信息量很大!你从哪里得到这个信息的?你读过类似的书吗?还是你自己检查字节码?我一直对如何用不同的语言了解东西是如何工作的感兴趣@MarkusWeninger这是熟悉Kotlin属性语义和使用内置“ShowKotlin字节码”功能的结合。
fun doSomething(double: (Int) -> Int) {
    double(i)
}