在Kotlin Set界面中调用add方法时未解决的引用错误
如果我使用Set接口引用,并尝试调用add方法,则会得到一个未解决的引用错误:
fun main(args : Array<String>) { val set = HashSet<Integer>() set.add(Integer(1)) //OK val seti : Set<Integer> = HashSet<Integer>() seti.add(Integer(2)) //FAILING: Unresolved reference to add** }
我不明白,行为。 Java的设置界面有一个添加方法,我期望Kotlin一个是扩展版本,而不是有更少的方法。
PD1:我在Idea IDE中遇到同样的错误,或者用gradle构建。 PD2:使用kotlin 1.0.0-beta-4584
Kotlin将Java的Set
接口分为两个接口: Set
和MutableSet
。 后面的接口声明了变异的方法,比如你正在寻找的add
方法。
通常,像MutableSet
这样的接口扩展了Set
接口,像HashSet
实现实现了MutableSet
接口。 然后可以使用Set
接口传递一个只读实例,以帮助避免常见的错误发生。
关于你的代码的一些说明,请参阅@ nhaarman关于Set
接口的回答 ,以及为什么你有编译器错误。 这个答案纯粹是为了获得更多的信息:
首先,您可以使用hashSetOf()
函数而不是HashSet
构造函数,尽管使用构造函数很好,但它并不常见。
val mySet = hashSetOf<Int>()
你应该使用Int
而不是Integer
。 你没有收到编译器的警告,因为你应该让Kotlin决定什么时候它正在讨论关于Int
, Long
, Byte
等的原语或者类。不要忽略这个警告。 文档中映射类型的表可能不清楚,它适用于相同类型的基本和盒装版本,除非您需要基本数组,不用担心使用哪一个。
不要实例化Integer
类,如调用Integer(1)
或Int(1)
。 相反,使用类似下面的代码 – 它让Kotlin为你做拳击:
val mySet1 = hashSetOf(1, 2, 3) // makes a HashSet<Int> which in Java is HashSet<Integer> val mySet2 = hashSetOf<Int>() // makes a HashSet<Int> which in Java is HashSet<Integer> mySet2.add(1) mySet2.add(2) mySet2.add(3)
而如果你想在初始化一个集合的时候把这个集合的构建包装到构造中并返回只读接口,那么你有很多选择。 其中一些是:
val mySet: Set<Int> = hashSetOf<Int>().apply { // do logic that adds to set (`this` is the set) }
要么:
val mySet: Set<Int> = run { val tempSet = hashSetOf<Int>() // do logic that adds to set tempSet }
要么:
val mySet = someFunc() fun someFunc(): Set<Int> { val tempSet = hashSetOf<Int>() // do logic that adds to set return tempSet }
请参阅函数的文档: apply() , let() , run()和with()
我有一个相当无用的扩展函数在我自己的库中,使得它清楚,当我想要一个只读接口,因为铸造产生一个警告,我不总是要在声明中指定冗余类型。 这是为了可读性而进行的扩展:
@Suppress("USELESS_CAST") fun <T: Any> MutableSet<T>.readonly(): Set<T> = this as Set<T>
用法是:
val mySet = hashSetOf<Int>().apply { // logic that builds the set }.readonly() // inferred type of mySet is Set<Int>