Статьи

Котлин месяц пост 3: безопасность

вступление

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

Нулевая безопасность

Это одна из самых рекламируемых особенностей Kotlin, из того, что я видел. Лично это немного lateinit меня, но некоторые встроенные делегаты свойств, такие как lazy и lateinit являются полезными обходными путями.

Вот безопасность, которую обеспечивает Колтин: переменная не может содержать null если ее тип не указывает, что она может быть обнуляемой. Вы можете объявить тип как обнуляемый, поместив ? в конце имени типа. Например, для переменной, которая может содержать null или String , ее тип будет String? , Это первый шаг нулевой безопасности.

Следующим шагом является то, что вы не можете напрямую вызывать методы или свойства из переменной NULL. Чтобы безопасно разыменовать обнуляемый объект, вы должны поместить ? до . , Этот оператор возвращает значение null если разыменовываемый объект имеет значение null , либо возвращает результат использования метода или свойства. Например, есть ли String? переменная с именем str , и мы хотим выяснить, пуста ли она, мы бы назвали ее с помощью str?.isEmpty() . Результатом является либо null , true , либо false . С помощью следующего оператора мы можем использовать это значение null для обозначения true .

Следующий оператор, часто называемый оператором elvis, так как он выглядит так, как будто это помпезный смайлик, помогает нам превратить null значения в значения по умолчанию. Он работает так же, как троичный оператор (которого у Котлина на самом деле нет, поскольку его блок if / else является выражением, а не оператором), за исключением того, что левая часть представляет собой комбинацию левого и среднего тернарного оператора. Это или оценивает к null или желаемому типу. Если это действительно как null , это использует правую сторону, если оператор. Итак, наша String? Пример выше стал бы str?.isEmpty() ?: true , который возвращает все, что возвращает isEmpty() , или же true если str был null . Кстати, ?: Часть была оператором.

Последний кусок головоломки это !! оператор. Это способ сказать компилятору одну из двух вещей. Либо «я предпочел бы получить исключение NullPointerException чем иметь дело с нулевой безопасностью» »или« »я знаю, что тип говорит, что он может быть null , но я могу гарантировать, что он не будет null ; по крайней мере, на данный момент.

Теперь, из-за взаимодействия с Java, Kotlin не может дать никаких гарантий об обнуляемости типов, поступающих из Java-кода. Он идет прагматическим путем и позволяет разработчику решить (и, если нужно, разобраться с последствиями), может ли он быть null или нет. Аннотации также могут использоваться для указания компилятору. Проверьте их документацию по взаимодействию Java с нулевой безопасностью для получения дополнительной информации.

Умный Кастинг

Интеллектуальное приведение — это отличная небольшая функция, которая, хотя в большинстве случаев и не встречается достаточно часто, действительно полезна для очистки вашего кода. Скажем, у вас есть такой код:

1
2
3
4
if(someVar instanceof SomeType) {
   SomeType anotherVar = (SomeType)someVar;
   
}

Этот вид кастинга — такая боль. Как только вы определили, что someVar имеет тип SomeType , вы не можете просто использовать его, как если бы он был. Нет, сначала вам нужно создать другую переменную (или, если вам «повезет», вы можете сделать это без новой переменной для однострочного выражения, но затем вам понадобится другой набор скобок для приведения — ((SomeType)someVar)... ) а так же выпишу состав актеров.

В Kotlin вы пишете это так:

1
2
3
if(someVar is SomeType) {
   
}

Во-первых, оператор проверки типа короче как is . Оператор броска тоже чище. Если бы нам нужно было использовать его в этом случае (чего мы не делали), это был бы var anotherVar = someVar as SomeType . Это не короче, но это чище.

Причина, по которой нам не нужно его приводить, заключается в том, что компилятор знает, что внутри блока someVar определенно является SomeType . Таким образом, нам даже не нужно было использовать другую переменную для этого, потому что она просто делает вид, что типом SomeType является SomeType вместо того, что было объявлено.

Интересно отметить, что это относится и к обнуляемости. Со String? это не то же самое, что String , а скорее супертип, это может быть умный бросок из String? в String :

1
2
3
if(someStr != null) {
   … as if someStr is no longer a nullable type
}

Тем не менее, у умного кастинга есть предел. Если рассматриваемая переменная потенциально может быть изменена другим потоком в любое время, она этого не сделает. Следовательно, интеллектуальное приведение может быть применено только к final переменным (значениям) или локальным переменным (созданным внутри функции).

Посмотрите документацию Kotlin по умным броскам, если вы хотите узнать больше.

Дженерики

Скажу прямо, у Kotlin есть лучшие дженерики, чем у Java. ‘Достаточно.

Я просто шучу. А если серьезно, дженерики Котлина лучше; они могут даже позволить вам делать вещи, которые Java не будет компилировать. Я не могу привести вам пример, но я однажды заметил пример StackOverflow, где кто-то пытался превратить свой код Kotlin в код Java, но не смог, потому что код Java не позволяет использовать дженерики определенным образом, но, к счастью, байт-код прощает и позволяет Kotlin сделать это.

Выйдя за пределы этого, Kotlin также использует дисперсию сайта объявления в качестве основной дисперсии, а не дисперсию сайта использования Java. Он также следует тому же синтаксису, что и дисперсия в C # (с использованием out и in вместо _ extends или _ super ), что в большинстве случаев легче понять. Поскольку я не очень хорош в объяснении этого материала, я хотел бы просто указать вам на документацию Котлина .

Встроенные функции и Reified Generics

Kotlin позволяет вам определять встроенные функции (функции, которые скомпилированы таким образом, что при вызове в коде он фактически «копирует» код из функции в место, где она вызывается), что может быть действительно полезным [и является только предлагается использовать] при создании функций, которые принимают лямбда-выражения и ссылки на методы, которые вызываются внутри, поскольку это тоже может быть встроено, без фактического создания объекта функции. Еще одна интересная особенность встроенных функций — это возможность иметь обобщенные обобщенные элементы (обобщенные элементы без стирания типов), поскольку в своем встроенном состоянии компилятор может фактически знать, что представляет собой фактический тип (при условии, что это не был обобщенный тип для начала с ). На самом деле есть множество вещей, которые можно сделать с помощью встроенных функций, поэтому вы должны проверить их в документации Kotlin .

Outro

На этом мой список функций безопасности заканчивается в Котлине. Вы должны просто пойти и влюбиться в Kotlin сейчас, как и я. Даже если ты не сделаешь этого сейчас, у меня все еще есть сообщение на следующей неделе, чтобы повлиять на тебя, так что с нетерпением жду этого.

Ссылка: Kotlin Month Post 3: Безопасность от нашего партнера JCG Джейкоба Циммермана в блоге « Идеи программирования с Джейком» .