首页 文章

强制null为非可空类型

提问于
浏览
1

有没有办法将null堵塞到一个非可空类型中,某种“我知道我在做什么”?

我想制作一个双重链表:

data class Node(var prev: Node, var next: Node, val value: Int)

我可以保证这个列表在初始化之后,在添加第一个节点之后但在第二个节点之前,始终至少有两个元素 . 我想保证prev和next永远不会为null .

我认为我会尝试的一件事是编写一个特殊的构造函数来初始化第一个和第二个节点 constructor(v1: Int, v2: Int) : this(Node(this, this, v1), v2) ,但是在进入正文之前不会对 this 做任何事情 .

3 回答

  • 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)
    

    我希望学习开销可以减少一点,但这比null-able next / prev更好 .

  • 1

    我'm wondering if we'在kotlin做同样的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

  • 0

    您可以通过提供接口或 sealed class 来抽象 Node 保持其引用的方式 .

    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()
    }
    

    这种方法将抵消您对可空类型的需求 . 它不是非常高效,而是一种获得编译时类型安全性的声明方式 .

相关问题