如何将实现委托给Kotlin中的可变属性? [英] How can I delegate an implementation to a mutable property in Kotlin?

查看:170
本文介绍了如何将实现委托给Kotlin中的可变属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

至于我的理解,在Kotlin中委托实现的想法是避免看起来像这样的代码:

As to my understanding, the idea of delegating an implementation in Kotlin is to avoid code that looks like this:

class MyClass(val delegate : MyInterface) : MyInterface
{
    override fun myAbstractFun1() = delegate.myAbstractFun1()
    override fun myAbstractFun2() = delegate.myAbstractFun2()
    // ...
}

相反,我们可以写下面的代码应该这样做:

Instead, we can write the following code which should do the same:

class MyClass(val delegate : MyInterface) : MyInterface by delegate

现在,我想要委托成为一个可变变量,即我的代码如下所示:

Now, I'd like delegate to be a mutable variable, i.e. my code looks like this:

var delegate : MyInterface = MyImplementation()
object MyObject : MyInterface by delegate

所以如果我委托了每一个摘要我自己喜欢委托的方法,就像在第一个例子中一样,更改 delegate 的值确实会改变方法的行为。但是,上面的代码编译为这个Java代码:

So if I'd delegated every abstract method to delegate by myself like in the first example, changing the value of delegate does change the behaviour of the methods. However, the above code compiles to this Java code:

public final class MyObject implements MyInterface {
    public static final MyObject INSTANCE;
    // $FF: synthetic field
    private final MyInterface $$delegate_0 = MyObjectKt.access$getDelegate$p();

    @NotNull
    public String myAbstractFun1() {
        return this.$$delegate_0.myAbstractFun1();
    }

    @NotNull
    public String myAbstractFun2() {
        return this.$$delegate_0.myAbstractFun2();
    }
}

显然,不是仅仅使用 delegate 字段,Kotlin编译器决定在创建 MyObject 到最终字段时复制它 $$ delegate_0 ,当我更改委托的值

So obviously, instead of just using the delegate field, the Kotlin compiler decides to copy it when creating MyObject to a final field $$delegate_0, which is not modified when I change the value of delegate

时,它没有被修改这样做的解决方案,而不是手动委派每个方法?

Is there a better solution for doing this instead of delegating every method manually?

推荐答案

可悲的是,据我所知,没有办法改变委托通过更改原始属性内容,您仍然可以通过以不可变的方式工作并复制对象来执行类似操作:

Sadly, as far as I know there is no way of changing the delegate by changing the original property content, but you might still be able to do something similar by working in an immutable way and copying the object:

interface MyInterface {
  fun foo():Int
}

data class MyClass(val delegate : MyInterface) : MyInterface by delegate

object ImplementationA: MyInterface { override fun foo() = 7 }
object ImplementationB: MyInterface { override fun foo() = 5 }

val objA = MyClass(ImplementationA)
println(objA.foo()) // returns 7

val objB = objA.copy(ImplementationB)
println(objB.foo()) // returns 5
println(objA.foo()) // still 7

希望这仍然有用。

这篇关于如何将实现委托给Kotlin中的可变属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆