重新分配 Kotlin 中的函数体

huangapple go评论59阅读模式
英文:

Reassigning function body in Kotlin

问题

我需要根据提供给构造函数的对象更改返回函数(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
    }
}

但我对是否以正确的方式实现有一些疑虑。请给出您的意见,从资源消耗和整体实现的角度来看,哪种方式更有效。谢谢。

为了在大量计算(递归)的条件下实现切换返回值的最有效方式,既要节省处理能力又要节省内存能力。

英文:

I need to change return function ( modify() method) in accordance with the object provided to the constructor. I see two ways to do it:
Via function body reassign:

class Modifier&lt;T&gt;{
    lateinit var func: ()-&gt;T

    constructor(sendable: Sendable&lt;T&gt;){
        func = {  sendable.send() }
    }
    constructor(modifier: Modifier&lt;T&gt;){
        func = {  modifier.modify() }
    }
    fun modify():T{
        return func()
    }
}

and through intermediate variable:

class Modifier&lt;T&gt;{
    var result:T

    constructor(sendable: Sendable&lt;T&gt;){
        result = sendable.send()
    }
    constructor(modifier: Modifier&lt;T&gt;){
        result = modifier.modify()
    }
    fun modify():T{
        return result
    }
}

But I have some doubts if it is implemented in the correct way. Please give your opinoin how it is effective from the point of view of resource consumption and overall realization. Thanks.

to have the most effective way of switching returning value in conditions of the huge calculation amount (recursion) saving both processing and memory capabilities.

答案1

得分: 2

第一个分配给func一个函数。所以,每次调用modify()时,结果都将被重新计算:

调用 Modifier.modify()
  调用 Modifier.result()
    计算分配的函数(可能是一个长时间的调用)
  返回结果
返回结果

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

调用 Modifier.modify()
  // 不再计算,结果已经在这里,直接返回
返回 Modifier.result

所以这取决于你的需求 - 是要计算一次结果,还是每次都重新计算。

英文:

The first one assigns to the func a function. So, each time you would call modify() the result will be recalculated:

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

The second one, however, caches the result (the result is assigned to the result when the object is constructed).

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

So it depends on what you need - to calculate the result once, or recalculate it each time.

答案2

得分: 1

你两个选项中的第一个是唯一一个符合您在注释中描述的要求的选项,即您希望每次调用modify()时都重新计算值。您必须存储函数引用以便能够多次调用它。函数引用将捕获对您的Sendable或Modifier实例的引用,因此即使在此类之外没有其他引用,它也会保留在内存中。

(顺便说一下,对于在每个构造函数或init块中初始化的属性,lateinit是不必要的。)

您可以将您的语法简化如下。定义一个 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()
    }
}
英文:

The first of your two options is the only one that does what you describe in the comments, that you want the value recalculated every time modify() is called. You have to store the function reference to be able to call it repeatedly. The function reference will capture a reference to your Sendable or Modifier instance, so it will stay in memory even if not referenced elsewhere outside this class.

(By the way, lateinit is unnecessary for a property that is initialized in every constructor or in an init block.)

You can shorten your syntax as follows. It seems a little weird to define a lambda to do nothing but call a single function so this syntax is a little more idiomatic, although there isn't a firm convention on this. The compiler will treat it the same.

class Modifier&lt;T&gt;{
    var func: ()-&gt;T

    constructor(sendable: Sendable&lt;T&gt;){
        func = sendable::send
    }
    constructor(modifier: Modifier&lt;T&gt;){
        func = modifier::modify
    }
    fun modify():T{
        return func()
    }
}

huangapple
  • 本文由 发表于 2023年3月9日 20:03:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684355.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定