Intereting Posts
Джексон-десериализация – классы данных Kotlin – значения по умолчанию для отсутствующих полей на картографе Каков правильный способ развёртки и обработчиков маршрутов Ktor для типичной реализации REST? модульный тест LogstashEncoder настроен правильно Преобразование единиц измерения в километры до миль не возвращает ожидаемый результат Написание JSP в kotlin с maven – Ошибка создания класса сервлета, ClassNotFoundException Нельзя использовать значение argb color int в Kotlin? Kotlin – как получить значение атрибута аннотации Android Kotlin: java.lang.NoClassDefFoundError: сбой разрешения: <KotlinObject> Android Kotlin – Невозможно планировать уведомление для будущей даты с помощью диспетчера аварийных сигналов Как легко потреблять продюсера канала Kotlin на Java? Создание несвязанного сервиса в Котлине Как создать вызванное время Уведомление, которое работает на всех устройствах Android JAX-RS (Apache CXF) Контекстная инъекция через сеттер Не удалось уменьшить список логических элементов в kotlin Общий код между сервером Kotlin и клиентскими проектами с использованием Gradle

Смарт-бросок в «Boolean» невозможно после изменения стоимости

Ошибка во втором println:

Смарт-бросок в «Boolean» невозможно, потому что «r.isSquare» является изменчивым свойством, которое к этому моменту могло быть изменено

fun main(args: Array<String>) { val r: Rectangle = Rectangle(5,5) println(r.isSquare) r.isSquare = true println(r.isSquare) // error but works with println(r.isSquare?:false) } data class Rectangle(var height: Int, var width: Int){ var isSquare: Boolean? = null } 

Если оно было null, оно напечатало бы null, как и первый println, почему я должен это делать?

Изменить 2

Спасибо за все ваши ответы, что я понимаю сейчас: First println

 println(message: Any?) 

Второй println

 println(message: Boolean) 

Потому что r.isSquare = true make доверяет компилятору, что isSquare имеет значение Boolean и не больше Boolean?

Edit2

Вот как я обрабатываю компилятор, чтобы сохранить доверие isSquare логическим?

 fun main(args: Array<String>) { val r: Rectangle = Rectangle(5, 5) println(r.isSquare) r.isSquare = true as Boolean? // if no cast, he will try wrong println signature println(r.isSquare) } data class Rectangle(var height: Int, var width: Int){ var isSquare: Boolean? = null } 

Так как r.isSquare является изменчивым свойством, компилятор не может использовать его в качестве свойства, отличного от null после нулевой проверки.

Вы можете использовать let :

 r.isSquare.let { println(it) } 

let читает значение r.isSquare только один раз и дает то же значение, что it внутри лямбда. Так что вам не нужно использовать ? или !! для доступа к логическому значению даже после нулевой проверки.

Из спецификации Котлина :

Язык использует информацию о предыдущих проверках для null, проверит типы (is,! Is), операторы безопасного вызова (?.) И Nothing-возвращающее выражение для вывода дополнительной информации о типах переменных (кроме тех, которые явно указаны или выведены из инициализаторов в их объявления), которые могут быть более конкретными в определенных блоках или даже выражениях. Эта информация затем используется для обеспечения более широкого набора операций над этими выражениями и для выбора более конкретных перегрузок.

 fun main(args: Array<String>) { var x : Any x = "" x.toUpperCase() // OK, smart cast to String } 

Первый println использует этот println(message: Any?)

Поскольку вы назначаете true для isSquare next, компилятор пытается интеллектуально отбросить isSquare к Boolean типу, когда вы пытаетесь его распечатать. Но это не могло быть умным, потому что свойство является изменяемым типом.

Если вы удалите строку, r.isSquare = true , тогда компилятор не попытается использовать смарт- r.isSquare = true в Boolean и использует println с Any? как параметр.

Для того, чтобы он работал, вам нужно добавить некий нулевой вызов (!!) после вашей переменной. Либо r !!. IsSquare, либо r.isSquare !!

 fun main(args: Array<String>) { val r: Rectangle = Rectangle(5,5) println(r.isSquare) r.isSquare = true println(r.!! isSquare) } data class Rectangle(var height: Int, var width: Int) { var isSquare: Boolean? = null } 

Поскольку isSquare является изменяемым свойством (var). Это означает, что между строками, где вы пишете значение, а затем читаете, другой поток может изменить его и получить из него NPE.

 r.isSquare = true //Another thread set r.isSquare = null println(r.isSquare) // you get a null pointer exception 

Вы должны проверять свойство nullability каждый раз, когда вы работаете с nullable vars.

Потому что функция println () в Android не поддерживает Boolean ?, а Boolean? с изменчивым свойством в kotlin не может быть развернуто автоматически умным броском Kotlin.

Попробуйте String? или Int? или любые типы с изменяемыми и обнуляемыми свойствами, получат то же самое.