В Kotlin Как я могу конвертировать Int?к Int - PullRequest
21 голосов
/ 05 марта 2012

Я использую HashMap<Int, Int> в Kotlin, и когда я get из него, тип возвращаемого значения Int?.

Как я могу преобразовать Int? в Int?

До сих пор я пытался использовать Int?.toInt(), но похоже, что возвращается Int?.

Я пишу функцию Фибоначчи, и мой код выглядит так:

val fibMemo : Map<Int, Int> = HashMap<Int,Int>()
fun fibN(n:Int) : Int {
    if (n == 0 || n == 1) return 1
    if (fibMemo.containsKey(n))
        // Error here: Type mismatch: inferred type is Int? but Int was expected
        return fibMemo.get(n)?.toInt()
    else {
        val newNum : Int = fibN(n-1) + fibN(n-2)
        fibMemo.put(n, newNum)
        return newNum
    }
}

Ответы [ 7 ]

21 голосов
/ 28 декабря 2015

Прямой ответ, используйте оператор !! , чтобы подтвердить, что вы доверяете значению, НЕ равному нулю, и, следовательно, измените его тип на ненулевой эквивалент.Простой пример, показывающий утверждение, разрешающее преобразование (которое применимо к любому типу, допускающему значение NULL, а не только к Int?)

val nullableInt: Int? = 1
val nonNullableInt: Int = nullableInt!! // asserting and smart cast

. Другой способ преобразования значения - проверка на ноль.Бесполезно в приведенном выше коде, но в другом коде (см. Проверка на нулевое значение в условиях ):

val nullableInt: Int? = 1
if (nullableInt != null) {
   // allowed if nullableInt could not have changed since the null check
   val nonNullableInt: Int = nullableInt
}

На этот вопрос также отвечает идиоматический вопрос об обнуляемости: В Kotlin, каков идиоматический способ иметь дело со значениями Nullable, ссылками или преобразованием их

8 голосов
/ 05 марта 2012

Чтобы преобразовать Int? в Int, используйте метод sure().

Оскорбительная строка должна выглядеть следующим образом:

return fibMemo.get(n).sure()

Вызов метода sure() - это способ Kotlin (вскоре будет заменен специальной языковой конструкцией), чтобы обеспечить необнуляемость Поскольку в Java нет обозначений обнуляемых и ненулевых типов, нам нужно позаботиться о точке интеграции. Пожалуйста, прочитайте удивительную историю нулевой безопасности в документации Kotlin.

источник

Предупреждение : приведенная выше информация больше не сохраняется. sure был заменен на !!. Смотри: http://blog.jetbrains.com/kotlin/migrating-sure/

2 голосов
/ 20 мая 2017

Самый простой способ - использовать нулевую проверку

var a : Int? = 12
var b : Int      
b = a // error!
b = if(a != null) a else -1    //automatic typecast from Int? to Int

Более подробную информацию о бросках с нулевым типом можно получить здесь: Нулевая безопасность - Kotlin

2 голосов
/ 12 ноября 2015

Вы также можете использовать функцию getOrPut , чтобы избежать включения / вставки вашего кода. См

val fibMemo = HashMap<Int, Int>()
fun fibN(n: Int): Int = when {
    n < 0 -> throw IllegalArgumentException("fib is not applicable to $n")
    n == 0, n == 1 -> 1
    else -> fibMemo.getOrPut(n) { fibN(n - 1) + fibN(n - 2) }
}
2 голосов
/ 05 марта 2012

Помимо проверки наличия ключа, вам также необходимо убедиться, что возвращаемое значение не равно null, так как java.util.HashMap допускает null значения.

Вы можете сделать это, окружив ваш вызов get явной проверкой null или вызвав !! возвращаемого значения.

Ваш обходной путь для использования as IntIDEA будет помечено как предупреждение о небезопасном приведении, и поэтому не рекомендуется.

1 голос
/ 10 января 2019

Вы также можете использовать значение по умолчанию в нулевом регистре:

val int: Int val nullableInt: Int? = null int = nullableInt ?: 0

1 голос
/ 05 июня 2017

Короткий ответ: , вы не можете , если вы не решительно заявите компилятору, что nullable int не может и не будет null при использованиидва восклицательных знака или с помощью if statement;потому что int является subtype из int?

Вот пример.

val x:Int? = 1
val y: Int =2

x=y // No error
y=x // Error
y=x!! // No error
...