“数据”类对象的通用约束

时间:2019-02-26 05:37:55

标签: kotlin

我想在语义上限制地图,使其仅接受“数据”类对象类型作为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}的任何对象) }。是我唯一的选择反射和运行时断言吗?

2 个答案:

答案 0 :(得分:1)

我不知道这是否是最好的方法,但是您如何使用如下所示的属性。

SomeClass::class.isData

Kdoc说

  

true(如果此类是数据类)。

答案 1 :(得分:1)

  

我以为实现Cloneable接口使您的克隆方法公开了?

否,它只是一个标记器接口,它告诉受保护的Object.clone()方法不要抛出CloneNotSupportedException。实际上,实现Cloneable的类通常会覆盖clone()并将其公开,但这不是必须的。当然,如果您不知道确切的类型,那也没有帮助!

克隆机制是Java的早期部分,并且设计得不太好。 (Effective Java称其为“接口的一种非常非典型的使用,而不是要被模仿的一种。”)但是它仍然被使用,因此我们坚持使用它……

(另请参阅these related答案。)