我有这样的代码:
enum class Player { PLAYER, COMPUTER }
interface BoardCell {
val x: Int
val y: Int
var player: Player?
}
data class Cell(val x: Int, val y: Int, var player: Player?, var value: Int)
data class BoardCellClass(override val x: Int, override val y: Int, override var player: Player?) : BoardCell
data class Request(val board: MutableList<MutableList<BoardCellClass>>? = null, val occupied: MutableList<BoardCellClass>? = null)
class AI(board: MutableList<MutableList<BoardCell>>, private var occupied: MutableList<BoardCell>) {
private var board: MutableList<MutableList<Cell>> = board.map { it.map { Cell(it.x, it.y, it.player, 0) } .toMutableList() } .toMutableList()
}
// in main
val request = call.receive<Request>()
if (request.board == null || request.occupied == null) {
// respond with 403
} else {
val ai = AI(request.board, request.occupied) // Kotlin: Type mismatch: inferred type is MutableList<MutableList<BoardCellClass>>? but MutableList<MutableList<BoardCell>> was expected
// Kotlin: Type mismatch: inferred type is MutableList<BoardCellClass>? but MutableList<BoardCell> was expected
}
但它与底部评论中的内容有误。我究竟做错了什么?显然,有一个if语句会捕获无效,所以它不应该是MutableList<MutableList<BoardCellClass>>?
类型,而是MutableList<MutableList<BoardCellClass>>
,不是吗?
此外,MutableList<MutableList<BoardCellClass>>
与MutableList<MutableList<BoardCell>>
兼容,因为它实现了该接口,对吗?
答案 0 :(得分:1)
此外,
MutableList<MutableList<BoardCellClass>>
与MutableList<MutableList<BoardCell>>
兼容,因为它实现了该接口,对吗?
不,不是。这是variance的问题。正在寻找&#34; Kotlin方差&#34;会给你很多解释,但最简单的方法是查看为什么MutableList<BoardCellClass>
不是MutableList<BoardCell>
的子类型
val list: MutableList<BoardCellClass> = ...
val list1: MutableList<BoardCell> = list // illegal in actual Kotlin!
list1.add(object : BoardCell { ... }) // would add a BoardCell to a MutableList<BoardCellClass>
然后可以将相同的逻辑提升到一个级别,以查看MutableList<MutableList<BoardCellClass>>
不是MutableList<MutableList<BoardCell>>
的子类型。
显然,有一个if语句会捕获无效,所以它不应该是
MutableList<MutableList<BoardCellClass>>?
类型,而是MutableList<MutableList<BoardCellClass>>
,不是吗?
Kotlin smart的投射方式并不完全(尽管差异在大多数情况下并不相关)。它仍属于MutableList<MutableList<BoardCellClass>>?
类型,但如果在所需类型为MutableList<MutableList<BoardCellClass>>
的地方使用,则会自动投放。MutableList<MutableList<BoardCell>>
这里所需的类型为@implementation TableViewCell
- (void)awakeFromNib {
...
}
- (void) layoutSubviews {
[super layoutSubviews];
CGRect newFrame = UIEdgeInsetsInsetRect(self.layer.frame, UIEdgeInsetsMake(4, 0, 4, 0));
self.layer.frame = newFrame;
}
@end
,因此没有插入强制转换,并且可以为空的类型显示在错误消息中。
答案 1 :(得分:1)
MutableList&GT;兼容 MutableList&gt;,因为它实现了它 界面,对吧?
没有。在您的情况下,您可以使用out
关键字
class AI(board: MutableList<MutableList<BoardCell>>, private var occupied: MutableList<out BoardCell>) {
private var board: MutableList<MutableList<Cell>> = board.map { it.map { Cell(it.x, it.y, it.player, 0) } .toMutableList() } .toMutableList()
}
显然,有一个if语句可以捕获无效,所以它 不应该是
类型
您可以编写此代码,如果(不是其他)部分编译器以正确的方式理解您
if (request.board != null && request.occupied != null){
val ai = AI(request.board, request.occupied)
} else {
// respond with 403
}