Kotlin – 如何使用自定义名称制作地图代理?

我试图让我的头绕着财产代表,我有一个有趣的用例。 有没有可能有这样的事情:

class MyClass { val properties = mutableMapOf<String, Any>() val fontSize: Any by MapDelegate(properties, "font-size") } 

这将允许我使用地图作为fontSize存储fontSize ,但使用自定义键(即“font-size”)。

如果用于存储诸如可以通过变量( fontSize )访问的用于代码的CSS属性标记的特定用例,但是在遍历地图( font-size: 18px; )时可以正确渲染。

关于委托物业的文件是关于这个话题的很好的信息来源。 它可能比以下示例稍长一些:

 fun <T, TValue> T.map(properties: MutableMap<String, TValue>, key: String): ReadOnlyProperty<T, TValue> { return object : ReadOnlyProperty<T, TValue> { override fun getValue(thisRef: T, property: KProperty<*>) = properties[key]!! } } class MyClass { val properties = mutableMapOf<String, Any>() val fontSize: Any by map(properties, "font-size") } 

你可以简化一些事情,避免通过将Kotlin属性名称转换为CSS属性等效项来输入CSS属性名称,如下所示:

 fun <T, TValue> map(properties: Map<String, TValue>, naming:(String)->String): ReadOnlyProperty<T, TValue?> { return object : ReadOnlyProperty<T, TValue?> { override fun getValue(thisRef: T, property: KProperty<*>) = properties[naming(property.name)] } } object CamelToHyphen : (String)->String { override fun invoke(camelCase: String): String { return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, camelCase) } } fun <T, TValue> T.cssProperties(properties: Map<String,TValue>) = map(properties, CamelToHyphen) class MyClass { val properties = mutableMapOf<String, Any>() val fontSize: Any? by cssProperties(properties) } 

上面的示例使用Guava的CaseFormat

如果你想有可变属性,你的委托将不得不实现setter方法:

 fun <T, TValue> map(properties: MutableMap<String, TValue?>, naming: (String) -> String): ReadWriteProperty<T, TValue?> { return object : ReadWriteProperty<T, TValue?> { override fun setValue(thisRef: T, property: KProperty<*>, value: TValue?) { properties[naming(property.name)] = value } override fun getValue(thisRef: T, property: KProperty<*>) = properties[naming(property.name)] } }