Принудительная установка NULL в ненулевой тип - PullRequest
0 голосов
/ 09 декабря 2018

Есть ли способ превратить нуль в ненулевой тип с каким-то видом «Я знаю, что я делаю»?

Я хочу создать двусвязный список:

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 голосов
/ 09 декабря 2018

Вы можете абстрагировать способ, которым Node хранит свои ссылки, предоставив интерфейс или 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()
}

. Этот подход сведет на нет вашу потребность в обнуляемых типах.Это не очень эффективный, но декларативный способ обеспечить безопасность типов во время компиляции.

0 голосов
/ 10 декабря 2018

Мне интересно, делаем ли мы ту же самую головоломку adventofcode в kotlin

Я использовал свойства 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
    }
}

, но это было много текста, когда использование было достаточно контролируемым, чтобы быть безопасным

Если это та же головоломка, вы можете см. Это используется в контексте на github

0 голосов
/ 09 декабря 2018

Я могу создать свойства с пустыми полями поддержки.

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-способны следующий / предыдущий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...