我想在语义上限制地图,使其仅接受“数据”类对象类型作为kotlin中的值,如下所示:
class Test(
val test : Int
)
data class Test2 (
val test : Int
)
fun test(map : Map<String, /* compile error on Test, but accept Test2 or any other data class */>) {
}
我主要是想这样做,以便可以将地图中的所有内容都克隆为副本,但是当我这样做时:
fun <T: Cloneable> test(map : Map<String, T>) {
// test clone
map.map { it.key.uuid to it.value.clone() } .toMap() // error on .clone() Cannot access 'clone': it is protected in 'Cloneable'
}
但是我认为实现Cloneable
接口使您的克隆方法公开了吗?本质上,我在寻找编译时保证在该方法调用中所有数据都是可复制的(是原始类型,可以调用.copy()
的数据类或已实现{{1}的任何对象) }。是我唯一的选择反射和运行时断言吗?
答案 0 :(得分:1)
我不知道这是否是最好的方法,但是您如何使用如下所示的属性。
SomeClass::class.isData
Kdoc说
true
(如果此类是数据类)。
答案 1 :(得分:1)
我以为实现Cloneable接口使您的克隆方法公开了?
否,它只是一个标记器接口,它告诉受保护的Object.clone()
方法不要抛出CloneNotSupportedException
。实际上,实现Cloneable
的类通常会覆盖clone()
并将其公开,但这不是必须的。当然,如果您不知道确切的类型,那也没有帮助!
克隆机制是Java的早期部分,并且设计得不太好。 (Effective Java称其为“接口的一种非常非典型的使用,而不是要被模仿的一种。”)但是它仍然被使用,因此我们坚持使用它……