Какой тип Kotlin использовать для значения параметра lateinit Int - PullRequest
1 голос
/ 07 марта 2019

Kotlin не позволяет этого:

private lateinit var port: Int;

Что я могу использовать, чтобы пометить целочисленное значение как разрешающее латинит?

Я понимаю , почему это делаетне работает (Int примитивен), мне нужно знать что использовать вместо ?

Edit 1

Это не дубликат этого, потому чтоЯ хочу знать, что использовать в этом случае, а не почему это происходит: Почему Kotlin не позволяет использовать lateinit с примитивными типами?

Редактировать 2 Какпредложенный @Roland ниже - BitInteger работает для меня:

private lateinit var port: BigInteger;

Я просто использую его для генерации URL, поэтому он мне действительно нужен только в конкатенации строк.

Ответы [ 3 ]

1 голос
/ 07 марта 2019

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

  1. просто используйте значение по умолчанию, например:

    var port : Int = 8080
    
  2. использовать другой Number -тип вместо Int, например

    class Server {
      lateinit var port : Number
    }
    

    Затем вы можете позвонить port.toInt(), если вам нужно.Но: существует много Number -типов, поэтому сужение до, например, BigInteger может иметь смысл.В противном случае вы можете получить объекты, которые вы не хотите принимать в первую очередь.

  3. с использованием Delegates.notNull

    var port : Int by Delegates.notNull()
    

    , но: даже если вы сэкономите null -значение тогда, вы не можете проверить, была ли переменная инициализирована, поэтому вам просто нужно иметь дело с исключением, как только вы захотите получить к нему доступ ... не очень приятно, я думаю ... но если выконечно, вы получите значение, тогда это тоже может быть вам подходит.

  4. просто используйте Int? и пропустите lateinit, например:

    class Server {
      var port : Int? = null
    }
    

    Вместо ::port.isInitialized вы бы попросили port != null, но: вам нужно обработать возможное null -значение сейчас, но с ? это не должно быть такой большой проблемой.

  5. используйте Int? с Delegates.vetoable на тот случай, если вы не хотите принимать null -значения после того, как получили свое первое значение, что делает его в основном чем-то вроде lateinit; -)

    class Server {
      var port : Int? by Delegates.vetoable(null as Int?) {
        _, _, newValue -> newValue != null
      }
    }
    

    и проверьте снова, используя port != null, который теперь ведет себя подобно ::port.isInitialized

Не то, чтобы я был большим поклонником последних двух, поскольку они представляют null снова, но в зависимости от того, что вы делаете, это может быть совершенно нормально ...

Поскольку вы добавили что-то относительно String конкатенации, я бы еще больше использовал Int? здесь.Тогда вы все равно можете использовать что-то вроде:

url = "$host${port?.let { ":$it" }?:""}"
// or:
url = port?.let { "$host:$it" } ?: host
// or
url = listOfNotNull(host, port).joinToString(":")

То же самое не может быть проще с ::port.isInitialized?

1 голос
/ 07 марта 2019

Я не знаю идеальное решение, которое вы ищете, но я делаю это так (на случай, если вы на самом деле вынуждены использовать примитивный тип):

 class Example{
    private var _port: Int? = null

    var port:Int
         get() = this._port!!
         set(i) { _port = i }
    }

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

0 голосов
/ 07 марта 2019

Если ваш проект не является кроссплатформенным, очевидным решением будет

@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") lateinit var i: java.lang.Integer

, который имеет однозначное соответствие со значениями Int (в отличие от BigInteger).

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