在 Kotlin 中重新分配函数体 [已关闭]

Reassigning function body in Kotlin [closed]

提问人:Mobt 提问时间:3/9/2023 更新时间:3/9/2023 访问量:71

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章来用事实和引文来回答。

9个月前关闭。

我需要根据提供给构造函数的对象更改返回函数(modify() 方法)。我看到两种方法可以做到这一点: 通过函数体重新分配:

class Modifier<T>{
    lateinit var func: ()->T

    constructor(sendable: Sendable<T>){
        func = {  sendable.send() }
    }
    constructor(modifier: Modifier<T>){
        func = {  modifier.modify() }
    }
    fun modify():T{
        return func()
    }
}

并通过中间变量:

class Modifier<T>{
    var result:T

    constructor(sendable: Sendable<T>){
        result = sendable.send()
    }
    constructor(modifier: Modifier<T>){
        result = modifier.modify()
    }
    fun modify():T{
        return result
    }
}

但我有些怀疑它是否以正确的方式实施。请从资源消耗和整体实现的角度给出您的意见,即它是如何有效的。谢谢。

在计算量巨大的条件下,以最有效的方式切换返回值(递归),从而节省处理和内存能力。

函数 Kotlin 方法 返回

评论

0赞 tobias_k 3/9/2023
看起来问题是:存储函数本身并在以后(可能多次)对其进行评估,还是立即评估它并且只评估一次?显然,只有当函数始终产生相同的结果并且该结果是不可修改的时,这才有意义。如果是这样的话,后者应该更有效率。一种介于两者之间的方法可能是存储函数,但在计算完值后缓存该值。
0赞 Tenfour04 3/9/2023
没有理由使用从所有构造函数初始化的属性。lateinit
0赞 Mobt 3/9/2023
@tobias_k 如果问题不清楚,请原谅。目的是每次都通过将 modify() 函数链接到正确的函数来计算 modify() 函数:sendable.send() 或嵌套的 modifier.modify()。并且要做到这一点,而无需消耗内存和处理的额外临时变量,例如为 this.modify() 重新分配函数体,不参与或func: ()->Tvar result:T

答:

2赞 Cililing 3/9/2023 #1

第一个分配给 a 函数。因此,每次调用结果时都会重新计算:funcmodify()

call Modifier.modify()
  call Modifier.result()
    calculate assigned fun (potentially long call)
  return result
return result

但是,第二个缓存结果(在构造对象时将结果分配给结果)。

call Modifier.modify()
  // no more calculation, result is already here, just return it
return Modifier.result

所以这取决于你需要什么 - 计算一次结果,或每次重新计算。

1赞 Tenfour04 3/9/2023 #2

两个选项中的第一个选项是唯一一个执行您在注释中描述的选项,即您希望每次调用时都重新计算值。您必须存储函数引用才能重复调用它。函数引用将捕获对 Sendable 或 Modifier 实例的引用,因此即使未在此类之外的其他位置引用,它也会保留在内存中。modify()

(顺便说一句,对于在每个构造函数或块中初始化的属性来说,这是不必要的。lateinitinit

您可以按如下方式缩短语法。将 lambda 定义为除了调用单个函数之外什么都不做似乎有点奇怪,因此这种语法更习惯,尽管对此没有严格的约定。编译器将同样对待它。

class Modifier<T>{
    var func: ()->T

    constructor(sendable: Sendable<T>){
        func = sendable::send
    }
    constructor(modifier: Modifier<T>){
        func = modifier::modify
    }
    fun modify():T{
        return func()
    }
}