首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Kotlin中实现动态属性分配

在Kotlin中实现动态属性分配
EN

Stack Overflow用户
提问于 2021-05-06 13:42:28
回答 1查看 487关注 0票数 1
代码语言:javascript
复制
data class Person private constructor(
   var name: ObservableField<String> = ObservableField("Tony Starks"),
   var age: ObservableField<Int> = ObservableField(40),
   var gender: ObservableField<String> = ObservableField("Male"),
   var test: String = "Tony Starks",
) {
   operator fun set(key: String, value: String) {
       // Tried this approach but it didn't work.
       this[key] = value
   }
}

我想要实现的是这一点;

代码语言:javascript
复制
val person = Person()
person['test'] = "James Bond"

我已经能够用PHP实现同样的目标

代码语言:javascript
复制
class Person {
    private $name;
    private $age;
    private $gender;
  
    public __get($key) {
      return $this[$key];
    }
  
    public __set($key, $value) {
        $this[$key] = $value;
    }
}

在科特林有可能做到这一点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-06 14:12:14

这种行为是像Kotlin这样的强类型语言中的反模式。通常情况下,不要试图强迫强类型语言表现得像弱类型语言是明智的。在使用强类型语言时,您的整个思维和设计方式应该是不同的。

尽管如此,通过使类本身成为MutableMap和委托相关属性,可以获得类似的语法。您可以通过委托(如下面所示)或通过子类MutableMap使其成为HashMap。但是,如果使用的是属性委托,则不能将其设置为data class

代码语言:javascript
复制
class Person: MutableMap<String, Any?> by mutableMapOf() {
    var test: String by this
    init {
        test = "Tony Stark"
    }

    override fun toString() = "Person(test='$test')"
}

fun main()  {
    val person = Person()
    println(person)
    person["test"] = "Pepper Potts"
    println(person)
    person.test = "Happy Hogan"
    println(person["test"])
}

/** Prints:
Person(test='Tony Stark')
Person(test='Pepper Potts')
Happy Hogan
*/

这样做的缺点(类似于弱类型语言中的问题)是:

  • 如果您在检索属性之前忽略设置它的初始值,它就会崩溃。
  • 如果您在属性名中输入错误,它将崩溃。
  • 如果您在设置名称时输入了一个错误,它将不会更改所需的属性。

Kotlin之所以能够将属性委托给Map (尽管它通常是一个反模式),是因为它在处理运行时动态数据(如JSON )时使用过,您可以在类表示之间来回转换。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67419373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档