Комментарии 35
Надо заметить, попахивает очень плохой практикой. Например, тот же "Data class inheritance from other classes is forbidden" запрещен не просто так, и это "чтобы они не мозолили глаза" может потом привести к неочевидным поведениям и с трудом отлавливаемым ошибкам.
если вы действительно делаете это часто, то явно делаете что-то не то. Хотя сама по себе таблица вещь очень полезная, спасибо!
Все зависит от того чем заниматься.
Если писать приложение, то воевать с ошибками приходится чрезвычайно редко.
Если же писать либу, то часто.
У меня безусловный победитель по количеству использований — это UNCHECKED_CAST, 90% применений которого приходится на бездарные шаблоны (женерики), которые неспособны приводить типы.
Но бывают и эксклюзивы, типа:
class PLog(private val allowlog : Boolean = true) {
...
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
inline fun log( cb:()->String ) =
if (allowlog) note(indent.indent() + cb() + "\n")
...
Открывать поле я не хочу, а избавиться от ошибки синтаксическими способами я не смог.
Т.к. функция inline, то все ее тело подставляется в место использования и как бы получается что приватные поля и методы "используются" за пределами класса.
Я голосую за обыкновенный баг.
Так они и на самом деле используются, просто для них вгенерятся синтетический геттер с названием access$getAllowlog$p
. Если не предупредить об этом разработчика, то у приватного поля появится геттер (в виде статического метода), доступный из Java.
У приватных пропертей нет гетеров
Да и не в этом суть
Это публичная функция, что и как она использует внутри своей реализации никого за ее пределами волновать не должно и от того что она inline ничего не меняется
У приватных полей нет геттеров, но появляются статические методы для их чтения, если вы делаете публичную инлайн-функцию с их использованием. От того, что функция инлайн меняется то, что напрямую через взятие поля это поле приватное поле не прочитать (без setAccessible), поэтому тело этой функции будет содержать вызов специального метода на стороне "вызова". Посмотрите сами в bytecode viewer.
Для этих целей в 1.1 появилась аннотация @PublishedApi, применимая к internal-декларациям
- Мне совершенно не нужно, чтобы это поле было доступно конечному юзеру.
class A {
@PublishedApi
internal val allow = false
inline fun F(cb : () -> String) {
if (allow) println(cb())
}
}
fun main(a : Array<String>) {
val a = A()
println( a.allow ) //Мне НЕ надо чтобы был доступ
}
- Если бы я захотел сделать поле доступным, то я бы это сделал просто указав public, зачем вообще эта аннотация нужна?
Можете привести пример ее осмысленного использования?
Слово internal означает "доступно внутри модуля". Ваш main в том же модуле.
Мы не разрешаем ссылки и inline функций на приватные декларации, потому что это нарушает главный принцип работы с ними: изменения приватных деклараций не должно ломать клиентский бинарный код. Там выше подробно объяснили, почему код сломается, если разрешить ссылку на private.
Мы разрешаем ссылки на internal-декларации со специальной аннотацией, чтобы была возможность что-то не показывать клиентам из другого модуля. Лучше сделать не можем, к сожалению.
Вообще вопроса не понял.
А насчет создания списка для использования автодополнения (для чего ты, наверное, и сделал класс) я думал.
С этого начал, но оказалось, что пользоваться этим ничуть не удобнее чем отдельной таблицей т.к. искать сообщение все равно можно только по тексту.
Да и как-то жаба душит тащить кучу абсолютно ненужного кода в либу. По привычке.
У меня в статье выдержка только сообщений котлина, взятая из его исходников, так что ничего универсального в ней и быть не может.
Иметь авто-дополнение для известных типов, конечно, хорошо, но только ради этого тащить кучу кода в любой проект, по моему, неадекватно и для эксклюзивов это никак не поможет.
Типовой кейс: вылезает ошибка, которую надо исключить, копирую уникальную часть текста (с этим самые большие сложности т.к. в IntelliJ окно с сообщениями об ошибках — это боль), ищу его в таблице, копирую тип и втыкаю в исходник.
В кнопках, помимо войны с текстом сообщения в IntelliJ, это все очень быстро: Alt-Tab, F4, F7, Ctrl-V, Enter пара шевелений стрелками, Ctrl-C и уже Alt-Tab обратно с типом.
Хочу заметить, что это все — внутренние особенности компилятора, и мы не гарантируем, что они будут поддерживаться в будущем :)
А если я в vim пишу на Котлине?
И почему же? Язык, на котором можно писать только в одной IDE? Только не разводите холивар на тему "vim — не IDE", речь не об этом.
А если хочется узнать, что означает конкретный Suppress, и это непонятно из названия?
То что все меняется — это понятно и никто (надеюсь) не рассчитывает что этот список сообщений будет вечен
А вто то что ни нигде не опубликованы — это плохо т.к. писать программу надо здесь и сейчас, на этой версии языка, а не на некоей идеальной, которая когда-то появится.
Я это не к тому, что надо все бросать и делать немедленно этот список
В языке пока есть много принципиальных проблем, которые меня лично волнуют значительно больше чем список сообщений, типа практически виснущего процесса компиляции на некоторых инлайновых функций или рразмножение одинаковых классов при использовнии ::StatFunction
.
Для меня лично отсутствие списка ошибок особой проблемы не составляет т.к. "на скорость не влияет"
Пожалуйста, записывайте волнующие вас проблемы (особенно "практически виснущий" компилятор) в наш баг-трекер: https://youtrack.jetbrains.com/issues/KT
Типы сообщений компилятора Kotlin, которые нужно использовать в Suppress