Kotlin – 如何使用自定义名称制作地图代理?
我试图让我的头绕着财产代表,我有一个有趣的用例。 有没有可能有这样的事情:
class MyClass { val properties = mutableMapOf() val fontSize: Any by MapDelegate(properties, "font-size") }
这将允许我使用地图作为fontSize
存储fontSize
,但使用自定义键(即“font-size”)。
如果用于存储诸如可以通过variables访问的CSS属性标记( fontSize
)以用于代码的特定用例,但是在迭代地图( font-size: 18px;
)时可以正确呈现。
关于委托物业的文件是关于这个话题的很好的信息来源。 它可能比以下示例稍长一些:
fun T.map(properties: MutableMap, key: String): ReadOnlyProperty { return object : ReadOnlyProperty { override fun getValue(thisRef: T, property: KProperty<*>) = properties[key]!! } } class MyClass { val properties = mutableMapOf() val fontSize: Any by map(properties, "font-size") }
你可以简化一些事情,并避免通过将Kotlin属性名称转换为CSS属性等效项来键入CSS属性名称,如下所示:
fun map(properties: Map, naming:(String)->String): ReadOnlyProperty { return object : ReadOnlyProperty { 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.cssProperties(properties: Map) = map(properties, CamelToHyphen) class MyClass { val properties = mutableMapOf() val fontSize: Any? by cssProperties(properties) }
上面的示例使用Guava的CaseFormat
。
如果你想有可变属性,你的委托将不得不实现setter方法:
fun map(properties: MutableMap, naming: (String) -> String): ReadWriteProperty { return object : ReadWriteProperty { 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)] } }