是否可以通过某种“我知道自己在做什么”将null塞入不可为null的类型中?
我想创建一个双向链接列表:
data class Node(var prev: Node, var next: Node, val value: Int)
我可以保证,在添加第一个节点之后,但在第二个节点之前,此列表在初始化期间始终会至少有两个元素 。我想保证prev和next永远不会为空。
我想尝试的一件事是写一个特殊的构造函数来初始化第一个和第二个节点constructor(v1: Int, v2: Int) : this(Node(this, this, v1), v2)
,但这是行不通的,因为我不能用this
做任何事情进入身体之前。
答案 0 :(得分:1)
我想知道我们是否在科特林也做同样的adventofcode puzzle
我使用了Lateinit属性来允许大理石更改其在链表中作为节点的位置
class Marble(val marbleNumber: Long) {
lateinit var counterClockwiseMarble: Marble
lateinit var clockwiseMarble: Marble
}
最初是二传手
class Marble(val marbleNumber: Long) {
lateinit var counterClockwiseMarble: Marble
private set
lateinit var clockwiseMarble: Marble
private set
fun setCounterClockwise(m: Marble) {
this.counterClockwiseMarble = m
}
fun setClockwise(m: Marble) {
this.clockwiseMarble = m
}
}
但是当使用受到足够控制以确保安全时,这似乎是很多文字
如果是同样的难题,可以see this used in context on github
答案 1 :(得分:0)
我可以使用可为空的后备字段创建属性。
data class Node(val value: Int) {
private var _prev: Node? = null
var prev: Node
get() = _prev!!
set(value) {
_prev = value
}
private var _next: Node? = null
var next: Node
get() = _next!!
set(value) {
_next = value
}
constructor(prev: Node, next: Node, value: Int) : this(value) {
this.prev = prev
this.next = next
prev.next = this
next.prev = this
}
}
然后可以通过
进行初始化val node0 = Node(0)
val node1 = Node(node0, node0, 1)
我希望了解开销可以减少一点,但这比可空的next / prev好。
答案 2 :(得分:0)
您可以通过提供接口或Node
例如{p>来抽象sealed class
保留其引用的方式。
data class Node(val ref: Reference, val value: Int)
sealed class Reference {
class Forward(val next: Node): Reference()
class Backward(val prev: Node): Reference()
class Bidirection(val prev: Node, val next: Node): Reference()
}
此方法将消除您对可为null的类型的需求。它不是很有效,而是一种声明式方式来获得编译时类型安全。