Setter for 字段被类型投影删除
Setter for field is removed by type projection
我有以下 SSCCE:
class Foo(val bars: Map<Int, Bar<*>>) {
fun <Baz> qux(baz: Baz) {
val bar2 = bars[2]!!
bar2.bazes += baz
}
interface Bar<Baz> {
var bazes: MutableList<Baz>
}
}
这对我来说似乎很好,但编译器抱怨说:
Error:(5, 9) Kotlin: Setter for 'bazes' is removed by type projection
我什至不知道这意味着什么,更不用说如何更正它了。这是怎么回事,我该如何解决?
有几个小问题。暂时使用bars[2]!! as Bar<Baz>
,
w: (4, 20): Unchecked cast: Foo.Bar<Any?> to Foo.Bar<Baz>
e: (5, 20): Assignment operators ambiguity:
public operator fun <T> Collection<Baz>.plus(element: Baz): List<Baz> defined in kotlin.collections
@InlineOnly public operator inline fun <T> MutableCollection<in Baz>.plusAssign(element: Baz): Unit defined in kotlin.collections
Kotlin 不知道是将其处理为 bar2.bazes = bar2.bazes.plus(baz)
还是 bar2.bazes.plusAssign(baz)
。如果将其更改为 var2.bazes.add(baz)
或 val bazes
,歧义就会消失。
解决这个问题并移除不安全的强制转换会出现
e: (5, 20): Out-projected type 'MutableList<out Any?>' prohibits the use of 'public abstract fun add(element: E): Boolean defined in kotlin.collections.MutableList'
类型投影可以安全地做什么的问题。它被视为 out Any?
,因此您可以从列表中读取,但是 in Nothing
,这意味着您不能向列表添加任何内容。
从这个例子中不清楚您为什么要使用 *
。如果它不会引起任何其他问题,也许您可以取消 <Baz>
参数,例如
class Foo<Baz>(val bars: Map<Int, Bar<Baz>>)
问题: 您的 bars
属性 正在使用 "star projection",简单来说,就是:"I don't know the generic type of Bar
" .这反过来会导致一个问题:你只能从 MutableList
中 get 一些东西,adding 是被禁止的(因此错误消息:没有 Setter for bazes
!).
可能的解决方案:
class Foo<in Baz>(private val bars: Map<Int, Bar<in Baz>>) {
fun qux(baz: Baz) {
val bar2 = bars[2]!!
bar2.bazes.add(baz)
}
interface Bar<Baz> {
var bazes: MutableList<Baz>
}
}
我在这里更改的是,我将 Foo
类型化为 in Baz
,这意味着 Foo
在其类型中成为 逆变参数,因此只能使用 Baz
s。然后将相同的类型用于输入参数 bars
。因此,您现在可以将 添加 值到 bars.bazes
,因为关联的 MutableList
据说是 "Consumer" 的 Bar
s.
顺便说一句:使用 Baz
作为通用类型的名称不是 recommended - 您应该使用 T
更明显的是通用类型。
我知道,这是一个复杂的话题,我真的建议您进一步咨询好 documentation :)
plusAssign 问题
另一方面,+=
(plusAssign
运算符)的用法有点奇怪:
编译器抱怨无法选择正确的运算符:
Assignment operators ambiguity:
public operator fun Collection.plus(element: Any?): List >defined in kotlin.collections
@InlineOnly public operator inline fun
MutableCollection.plusAssign(element: Baz): Unit
defined in kotlin.collections
我试图将 bazes
显式转换为 MutableList
,这实际上解决了问题。然后编译器抱怨 unecessary 强制转换。老实说,我不知道如何正确处理这个问题,除非使用 add
;-)
我有以下 SSCCE:
class Foo(val bars: Map<Int, Bar<*>>) {
fun <Baz> qux(baz: Baz) {
val bar2 = bars[2]!!
bar2.bazes += baz
}
interface Bar<Baz> {
var bazes: MutableList<Baz>
}
}
这对我来说似乎很好,但编译器抱怨说:
Error:(5, 9) Kotlin: Setter for 'bazes' is removed by type projection
我什至不知道这意味着什么,更不用说如何更正它了。这是怎么回事,我该如何解决?
有几个小问题。暂时使用bars[2]!! as Bar<Baz>
,
w: (4, 20): Unchecked cast: Foo.Bar<Any?> to Foo.Bar<Baz>
e: (5, 20): Assignment operators ambiguity:
public operator fun <T> Collection<Baz>.plus(element: Baz): List<Baz> defined in kotlin.collections
@InlineOnly public operator inline fun <T> MutableCollection<in Baz>.plusAssign(element: Baz): Unit defined in kotlin.collections
Kotlin 不知道是将其处理为 bar2.bazes = bar2.bazes.plus(baz)
还是 bar2.bazes.plusAssign(baz)
。如果将其更改为 var2.bazes.add(baz)
或 val bazes
,歧义就会消失。
解决这个问题并移除不安全的强制转换会出现
e: (5, 20): Out-projected type 'MutableList<out Any?>' prohibits the use of 'public abstract fun add(element: E): Boolean defined in kotlin.collections.MutableList'
类型投影可以安全地做什么的问题。它被视为 out Any?
,因此您可以从列表中读取,但是 in Nothing
,这意味着您不能向列表添加任何内容。
从这个例子中不清楚您为什么要使用 *
。如果它不会引起任何其他问题,也许您可以取消 <Baz>
参数,例如
class Foo<Baz>(val bars: Map<Int, Bar<Baz>>)
问题: 您的 bars
属性 正在使用 "star projection",简单来说,就是:"I don't know the generic type of Bar
" .这反过来会导致一个问题:你只能从 MutableList
中 get 一些东西,adding 是被禁止的(因此错误消息:没有 Setter for bazes
!).
可能的解决方案:
class Foo<in Baz>(private val bars: Map<Int, Bar<in Baz>>) {
fun qux(baz: Baz) {
val bar2 = bars[2]!!
bar2.bazes.add(baz)
}
interface Bar<Baz> {
var bazes: MutableList<Baz>
}
}
我在这里更改的是,我将 Foo
类型化为 in Baz
,这意味着 Foo
在其类型中成为 逆变参数,因此只能使用 Baz
s。然后将相同的类型用于输入参数 bars
。因此,您现在可以将 添加 值到 bars.bazes
,因为关联的 MutableList
据说是 "Consumer" 的 Bar
s.
顺便说一句:使用 Baz
作为通用类型的名称不是 recommended - 您应该使用 T
更明显的是通用类型。
我知道,这是一个复杂的话题,我真的建议您进一步咨询好 documentation :)
plusAssign 问题
另一方面,+=
(plusAssign
运算符)的用法有点奇怪:
编译器抱怨无法选择正确的运算符:
Assignment operators ambiguity:
public operator fun Collection.plus(element: Any?): List >defined in kotlin.collections@InlineOnly public operator inline fun MutableCollection.plusAssign(element: Baz): Unit defined in kotlin.collections
我试图将 bazes
显式转换为 MutableList
,这实际上解决了问题。然后编译器抱怨 unecessary 强制转换。老实说,我不知道如何正确处理这个问题,除非使用 add
;-)