强制将null转换为非null类型

时间:2018-12-09 14:36:23

标签: kotlin

是否可以通过某种“我知道自己在做什么”将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做任何事情进入身体之前。

3 个答案:

答案 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的类型的需求。它不是很有效,而是一种声明式方式来获得编译时类型安全。