当前位置: 首页 > 知识库问答 >
问题:

虽然我有var(kotlin),但无法重新分配Val?

岑俊明
2023-03-14

我为数据类创建了一个var扩展属性,如下所示:

var Element.bitmap: Bitmap?
        get() = downloadImg(PLACE_HOLDER_URL) //Default
        set(value) = this.bitmap.let {
            it = value ?: return@let
        }

但是,当我尝试将“Val”重新分配给此行中的新值时,编译器会抱怨“Val无法重新分配”:

it = value ?: return@let  

我真的不明白为什么会这样??我有一个“var”位图属性而不是“val”,那么问题是什么?更重要的是,什么是解决方案或替代方案?

共有2个答案

和弘博
2023-03-14

为了创建自定义设置器,您需要通过field而不是it访问属性的后备字段,如下所示:

set(value) =  {
            field = value
        }
洪胤
2023-03-14

lambda中的变量是不可变的,它有一个变量位图的浅拷贝。

您应该使用字段分配到支持字段(实际变量)。

set(value) {
    value?.let { field = it }
}

函数创建变量的浅拷贝,这样,如果一个可见可变变量(var)被另一个线程更改,那么它就可以安全地使用,而不会有突变的风险。

示例:

class Test {
    var prop: Int? = 5
}

fun main() {
    val test = Test()
    thread {
        Thread.sleep(100)
        test.prop = null
    }
    if (test.prop != null) {
        Thread.sleep(300)  // pretend we did something
        println(test.prop)  // prints null even inside if check
    }
}

为了解决这些情况,使用了一个浅层副本,例如withlet,它传递这些内容的一个不可变的浅层副本。

class Test {
    var prop: Int? = 5
}

fun main() {
    val test = Test()
    thread {
        Thread.sleep(100)
        test.prop = null
    }
    test.prop?.let {  // `it` is a shallow copy, changes won't be reflected
        Thread.sleep(300)  // pretend we did something
        println(it)  // prints 5
    }
}

结论:它本身不是实际变量,因此即使您能够为它分配一些内容,更改也不会反映到实际变量。

编辑:扩展属性不能有后备字段,扩展实际上是getter和setter。

  • 您可以做的一件事是使用唯一标识符创建一个映射,您可以在其中存储值,但这可能无法被垃圾收集

代表团示例:

class ElementBitmapDelegate {
    private var value: Bitmap? = null
    
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Bitmap {
        return value ?: downloadImg(PLACE_HOLDER_URL).also { setValue(thisRef, property, it) }
        // return value or if value is null return from downloadImg() and set it to value
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, v: Bitmap?) {
        v?.let { value = it }  // if v is not null then set value to v
    }
}


var Element.bitmap: Bitmap? by ElementBitmapDelegate()

 类似资料:
  • 我试图在kotlin中编写一个函数,但我无法将值重新分配给函数参数,它说val不能重新分配。 当我试图分配一个值url=主页. it给我错误val不能重新分配,我是新的kotlin,我不明白是什么问题,很少帮助将不胜感激。

  • 我在IntelliJ中使用静态编程语言。 我有一段简短的代码 为什么在这个世界上它告诉我: 关于提到的变量,“Val不能重新分配”任何val实例都已完全更改为var。 为了确保这一点,我已经在其他类中更改了同名的变量,甚至还将类中的每个变量都更改为var,我仍然会遇到这个错误。 这与可拉伸的性质有关吗? 我错过了什么或做错了什么来得到这个错误,我如何修复它? 非常感谢。

  • 我有这两个函数,我试图修改元素。其中一个编译,另一个说“val不能重新分配”。以下函数有什么区别?为什么一个编译,另一个不编译? 编译的那个 那个说 无法重新分配Val

  • 问题:我无法实现从protobuf自动生成的对象。 如何复制:从micronaut初始值设定项生成一个项目,该项目具有:gRPC应用程序类型、Java 11、Kotlin。添加io。grpc:protoc gen grpc kotlin正在构建中。gradle,构建它,添加一个控制器,然后尝试实现GrpcdemoServiceGrpcKt。 建筑格拉德尔 格拉德尔。属性 其余的都和micronau

  • 我将JAVA\u HOME变量设置为follow path:/usr/lib/jvm/jdk11,当我放置以下命令:JAVA-version时,它显示当前版本,echo$JAVA\u HOME指示上述路径。当我启动tomcat时,会出现以下错误消息:既没有定义JAVA\u HOME,也没有定义JRE\u HOME变量。 我把一切都设置好了,但是公猫找不到它。