有没有办法在多个调用的静态函数中重用 Kotlin 中的变量?

Is there a way to reuse variables in Kotlin in static functions in multiple calls?

提问人:maybeJosiah 提问时间:7/5/2023 最后编辑:halfermaybeJosiah 更新时间:8/31/2023 访问量:244

问:

我刚刚发现函数参数在 Kotlin 中是不可变的。我期待可变性,但在我发现的官方文档中没有提到这一点。就我个人而言,我认为应该有某种方法可以在 Kotlin 中的多个静态函数中重用单个变量。这怎么可能与不可变的参数有关?我正在尝试不返回使用的值,只返回数组,重用它的索引或不同函数中使用的相同变量等值,而不需要访问其他函数的数据。像其他语言一样,数据事物可以传递和使用,但可能不会在其他函数中读取,但它支持编写事物并在静态函数范围内使用它。

我尝试过 Kotlin playground,我期待一个 var param 的东西,不存在。我尝试了数组和列表,发现在 Kotlin playground 中,成员可以设置,但不能设置原始数组或列表。我的问题是这是否会编译。有了它,我可以将所有变量装配在数组或列表中,并随心所欲地设置。无论如何,问题是:Kotlin 中的一组静态函数如何在多个调用中重用一个或多个变量(如 var)?这是为了提高效率,更多的变量,更多的垃圾回收,更慢的程序,我更喜欢更快的程序。

函数 Kotlin 编译参数 传递 静态方法

评论

1赞 Louis Wasserman 7/5/2023
对于初学者来说,在 Java 中修改函数参数从来没有做过任何事情,在 Java 或 Kotlin 中也是如此,这并不等同于仅仅使用一个新变量。其次,你似乎对性能及其工作方式有错误的印象,或者试图管理这样的变量会产生可以注意到的差异。第三,您似乎认为重用变量并将它们存储在公共位置可以提高性能,而不是损害性能。
0赞 maybeJosiah 7/5/2023
我知道在不创建新变量的情况下重用变量实际上确实有助于某些语言(包括 Javascript)的性能显着提高。如果可能的话,我正在尝试通过在多个函数调用中重用变量来分配更少的内存。如果我想在多个函数调用中使用一个内存分配会很好用。所有的人都可能是,也许是,也可能不是,也许不是,也许。
3赞 Louis Wasserman 7/5/2023
这种优化内存的方法实际上在 Java 或 Kotlin 中没有任何作用。不要。即使是最注重性能的代码也不会从中受益,而且它实际上可能会损害性能。

答:

1赞 broot 7/5/2023 #1

Kotlin 不支持通过引用传递函数参数。参数始终被复制。Kotlin 的主要目标平台也不支持它:Java 和 JavaScript。

如果你真的想这样做,你可以创建一个简单的包装器并传递它:

fun test(value: Wrapper<String>) {
    value.value = "foo"
}

data class Wrapper<T>(var value: T)

然而,这并不是真正的“Kotlin 方式”。在 Kotlin 或 Java 等语言中,我们假设函数/方法接收参数并返回新值。我们可以修改传递的对象,如果函数的名称清楚地提到了这一点,这并不被认为是一个坏的做法。但是,通过参数或替换调用方的变量返回结果,对于像 C 这样的语言来说,比 Kotlin/Java 更典型。我相信 Kotlin/Native 对指针有一些支持,所以在那里是可能的。

评论

0赞 maybeJosiah 7/5/2023
是否像 Array 或 MutableList 一样,像这个包装器一样,它编译为具有数组或列表的可用部分?
0赞 broot 7/5/2023
我不确定我是否理解正确,但是是的,Array 或 MutableList 也可以用作此类包装器。
0赞 maybeJosiah 7/5/2023
这回答了我的问题,是的,我在问这些是否可以用作这样的包装器。所有的人都可能是,也许是,也可能不是,也许不是,也许。
0赞 maybeJosiah 8/31/2023
我用它写了一个图书馆,所以我应该如何感谢你的帮助@broot?
-2赞 maybeJosiah 7/6/2023 #2

据我了解,任何具有属性的对象都可以重用该属性,包括 Array 和 List 以及 IntArray。不过,这并不是 Kotlin 的首选方式,正如 Louis Wasserman 所说,这可能会对性能产生负面影响。

据我了解,首选方法是让一个类与一个伴随对象,并在该伴随对象中有一个 var 事物和一个使用该 var 事物的函数。如果我喜欢静态函数和变量,请使用 @JvmStatic 来注释所有应该静态的内容。我知道在 Java 中,第一次和第二次工作,第一个较慢,第二个较快。

second 的唯一问题是每个变量一次只能执行一个函数调用。解决此问题的一个方法是为每个函数使用不同的变量。我发现数组和列表会根据函数调用而变化,并且在函数调用之外保持变化,无论是否为 val。

fun test(x:DoubleArray):DoubleArray {
    x[0]+=2.0;
    return x;
    //Works here at least on JVM
}

fun main() {
     ar:DoubleArray=DoubleArray(2);
    println(test(ar)[0]);
    println(ar[0]);
    //Both print 2.0 on JVM
    println(ar[1]);
}
class Test private constructor(){
    companion object {
        var variable:Double = 0.0;
        fun test() {
            Test.variable=2.0;
        }
    }
}

第一个是允许使用数组或列表部分的方式。其次是如何做一个静态变量的用法。我进行了测试,两者都可以在 Kotlin Playground 上使用的所有平台上运行。

对于重用变量,使用静态列表或数组并传递静态变量索引以供使用将允许静态变量异步。由于有些可能是先完成的较低指数,因此可能需要一个自由变量。根据我的经验,在 Java 中,函数速度按以下顺序排列:常规函数不是静态的较慢,静态函数是中间更改其参数的,静态函数仅以最快的速度更改静态变量。为了简单起见,我可能会尝试中间,但为了快速起见,请使用静态列表和可变票务系统。喜欢这个:

class XE private constructor() {
    companion object {
        @JvmStatic
        var ints:IntArray=IntArray(1);
        @JvmStatic
        var freeInts:BooleanArray=BooleanArray(1){true};
        @JvmStatic
        fun test(Int ticket=0) {
            XE.freeInts[ticket]=false;
            XE.ints[ticket]=2;
            //Use ints[ticket]
            XE.freeInts[ticket]=true;
        }
        @JvmStatic
        fun getTicket(free:BooleanArray):Int{
            Int index = 0;
            while (!free[index]&&index!=free.size) {
                index+=1;
            }
            return index;
        }
    }
}

为此,应该提供一张获得第一张票。我知道这是编译的,我在 Kotlin Playground 上尝试过,所有平台都可以。就像我在 Kotlin Playground 中的测试不包括 JS、IR 和 Wasm,但目前所有其他平台(JVM、JS、Canvas)都进行了测试。

评论

1赞 Community 7/10/2023
您的答案可以通过其他支持信息进行改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。