Приведение и проверка типов — Kotlin
Операторы is и !is
Используйте оператор is
или его отрицание !is
, чтобы проверить соответствует ли объект заданному типу
во время исполнения.
if (obj is String) { print(obj.length) } if (obj !is String) { // то же самое, что и !(obj is String) print("Not a String") } else { print(obj.length) }
Умные приведения
В большинстве случаев вам не нужно использовать явные приведения в Kotlin,
потому что компилятор отслеживает is
-проверки и явные преобразования
для неизменяемых значений и вставляет (безопасно) приведения автоматически, там, где они нужны.
fun demo(x: Any) { if (x is String) { print(x.length) // x автоматически преобразовывается в String } }
Компилятор достаточно умён для того, чтобы понимать, что приведения безопасны в случаях,
когда проверка на несоответствие типу (!is
) приводит к выходу из функции:
if (x !is String) return print(x. length) // x автоматически преобразовывается в String
или в случаях, когда приводимая переменная находится справа от оператора &&
или ||
, а соответствующая проверка
(обычная или отрицательная) находится слева:
// x автоматически преобразовывается в String справа от `||` if (x !is String || x.length == 0) return // x автоматически преобразовывается в String справа от `&&` if (x is String && x.length > 0) { print(x.length) // x автоматически преобразовывается в String }
Умные приведения работают вместе с when
-выражениями
и циклами while
:
when (x) { is Int -> print(x + 1) is String -> print(x.length + 1) is IntArray -> print(x.sum()) }
Заметьте, что умные приведения работают только тогда, когда компилятор может гарантировать, что переменная не изменится между проверкой и использованием. Точнее говоря, умные приведения будут работать:
- с локальными
val
переменными — всегда за исключением локальных делегированных свойств. ; - с
val
свойствами — если поле имеет модификатор доступаprivate
илиinternal
, или проверка происходит в том же модуле, в котором объявлено это свойство. Умные приведения неприменимы к публичным свойствам или свойствам, которые имеют переопределённые getter’ы; - с локальными
var
переменными — если переменная не изменяется между проверкой и использованием, не захватывается лямбдой, которая её модифицирует и не является локальным делегированным свойством; - с
var
свойствами — никогда, потому что переменная может быть изменена в любое время другим кодом.
Оператор «небезопасного» приведения
Обычно оператор приведения выбрасывает исключение, если приведение невозможно, поэтому мы называем его небезопасным.
Небезопасное приведение в Kotlin выполняется с помощью инфиксного оператора as
:
val x: String = y as String
Заметьте, что null
не может быть приведен к String
, так как String
не является nullable,
т. е. если y
— null, код выше выбросит исключение. Чтобы сделать этот код корректным для null-значений,
используйте nullable-тип в правой части приведения.
val x: String? = y as String?
Оператор «безопасного» (nullable) приведения
Чтобы избежать исключения, вы можете использовать оператор безопасного приведения as?
, который возвращает null
в
случае неудачи.
val x: String? = y as? String
Заметьте, что несмотря на то, что справа от
стоит non-null тип String
, результат приведения является nullable.
Стирание и проверка типов у Обобщений (Generics)
Котлин обеспечивает типобезопасность операций, связанных с обобщениями на этапе компиляции,
в то время как информация о типе аргумента обобщения недоступна во время выполнения программы.
Например, для List<Foo>
происходит стирание типа, что превращает его в List<*>
. В связи с чем,
нет способа проверить, принадлежит ли объект конкретному типу во время выполнения программы.
Учитывая это, компилятор запрещает is
ints is List<Int>
или list is T
(параметризированный тип).
Однако у вас есть возможность произвести проверку со «звёздными» проекциями.if (something is List<*>) { something.forEach { println(it) } // Элементы типа `Any?` }
Таким же образом, когда у вас есть статически определенный тип аргумента, вы можете произвести is
-проверку
или приведение с необобщенной частью типа. Заметьте, что в данном случае угловые скобки пропущены:
fun handleStrings(list: List<String>) { if (list is ArrayList) { // `list` приводится к `ArrayList<String>` путём "умного приведения" } }
Аналогичный синтаксис, но с пропущенным типом аргумента может использоваться для приведений,
которые не принимают типы аргументы: list as ArrayList
.
Встроенные (inline) функции с параметрами вещественного типа имеют свои
аргументы типа, встроенные на каждый момент вызова, что позволяет arg is T
проверять параметризованный тип, но если arg
является объектом обобщенного типа, его аргумент типа по-прежнему стираются.
inline fun <reified A, reified B> Pair<*, *>.asPairOf(): Pair<A, B>? { if (first !is A || second !is B) return null return first as A to second as B } val somePair: Pair<Any?, Any?> = "items" to listOf(1, 2, 3) val stringToSomething = somePair.asPairOf<String, Any>() val stringToInt = somePair.asPairOf<String, Int>() val stringToList = somePair.asPairOf<String, List<*>>() val stringToStringList = somePair.asPairOf<String, List<String>>() // Нарушает типобезопасность! fun main() { println("stringToSomething = " + stringToSomething) println("stringToInt = " + stringToInt) println("stringToList = " + stringToList) println("stringToStringList = " + stringToStringList) //println(stringToStringList?.second?.forEach() {it.length}) // Это вызовет исключение ClassCastException, так как элементы списка не являются строками }
Непроверяемые (Unchecked) приведения
Как упоминалось выше, стирание типов делает невозможным проверку типа аргумента обобщения на этапе выполнения, и обобщенные типы в коде могут быть недостаточно связаны друг с другом, чтобы компилятор обеспечил типобезопасность.
Тем не менее иногда мы имеем программную логику высокого уровня, которая подразумевает типобезопасность.
fun readDictionary(file: File): Map<String, *> = file.inputStream().use { TODO("Прочитать сопоставление строк с произвольными элементами.") } // Мы сохранили словарь (map) `Int`ов в файл val intsFile = File("ints.dictionary") // Warning: Unchecked cast: `Map<String, *>` to `Map<String, Int>` val intsDictionary: Map<String, Int> = readDictionary(intsFile) as Map<String, Int>
Компилятор выдает предупреждение для приведения в последней строке. Приведение не может быть полностью проверено во
время выполнения и нет дает гарантии, что значения в словаре (map) являются Int
.
Чтобы избежать непроверяемые приведения, вы можете изменить структуру программы: в примере выше
возможно объявить интерфейсы
и DictionaryWriter<T>
с типобезопасными имплементациями для различных типов. Правильное использование
вариативности обобщений также может помочь.
Для обобщенных функций, используемых встроенные (inline) функции с
параметрами вещественного типа приведение типа arg as T
является
проверяемым, до тех пор, пока тип arg
не имеет свои аргументы типа, которые были стерты.
Предупреждение о непроверяемом приведении можно убрать используя аннотации @Suppress("UNCHECKED_CAST")
.
inline fun <reified T> List<*>.asListOfType(): List<T>? = if (all { it is T }) @Suppress("UNCHECKED_CAST") this as List<T> else null
В JVM, массивы (
Array<Foo>
) сохраняют информацию о стираемом типе их элементов, и приведение типов к массиву частично проверяется: nullability и фактические аргументы для параметризированных элементов массива все еще стираются. Например, приведениеfoo as Array <List <String>?>
будет успешным, еслиfoo
является массивомList <*>
, независимо от того, является ли он nullable или нет.
Преобразование строки в целое число в Groovy
Наш мир глазами ИИ, пример. Источник: ArchDaily
1. Обзор
В этом кратком руководстве мы покажем различные способы преобразования из строки
в целое число
в Groovy.
2. Кастинг с
as
Первый метод, который мы можем использовать для преобразования, — это ключевое слово as
, которое аналогично вызову метода asType()
класса « :
@Test
void givenString_whenUsingAsInteger_thenConvertToInteger() {
def stringNum = "123"
Integer expectedInteger = 123
Integer integerNum = stringNum as IntegerassertEquals(integerNum, expectedInteger)
}
Как и выше, мы можем использовать int
:
@Test
void givenString_whenUsingAsInt_thenConvertToInt() {
def stringNum = "123"
int expectedInt = 123
int intNum = stringNum as intassertEquals(intNum, expectedInt)
}
3.
целое число
Другой метод — из расширения Groovy JDK для java.lang.CharSequence
:
@Test
void givenString_whenUsingToInteger_thenConvertToInteger() {
def stringNum = "123"
int expectedInt = 123
int intNum = stringNum.toInteger()assertEquals(intNum, expectedInt)
}
4.
Целое#parseInt
Третий способ — использовать статический метод Java Integer.parseInt()
:
@Test
void givenString_whenUsingParseInt_thenConvertToInteger() {
def stringNum = "123"
int expectedInt = 123
int intNum = Integer.parseInt(stringNum)assertEquals(intNum, expectedInt)
}
5.
Целое#intValue
Альтернативный метод — создать новый объект Integer
и вызвать его метод intValue :
@Test
void givenString_whenUsingIntValue_thenConvertToInteger() {
def stringNum = "123"
int expectedInt = 123
int intNum = new Integer(stringNum). intValue()assertEquals(intNum, expectedInt)
}
Или, в этом случае, мы также можем использовать просто new Integer(stringNum)
:
@Test
void givenString_whenUsingNewInteger_thenConvertToInteger() {
def stringNum = "123"
int expectedInt = 123
int intNum = new Integer(stringNum)assertEquals(intNum, expectedInt)
}
6.
Целое число#valueOf
Подобно Integer.parseInt()
, мы также можем использовать статический метод Java Integer#valueOf
:
@Test
void givenString_whenUsingValueOf_thenConvertToInteger() {
def stringNum = "123"
int expectedInt = 123
int intNum = Integer.valueOf(stringNum)assertEquals(intNum, expectedInt)
}
7.
Десятичный формат
И для нашего последнего метода мы можем применить класс DecimalFormat
Java :
@Test
void givenString_whenUsingDecimalFormat_thenConvertToInteger() {
def stringNum = "123"
int expectedInt = 123
DecimalFormat decimalFormat = new DecimalFormat("#")
int intNum = decimalFormat. parse(stringNum).intValue()assertEquals(intNum, expectedInt)
}
8. Обработка исключений
Таким образом, если преобразование не удается, например, если есть нечисловые символы, будет выдано исключение NumberFormatException
. Кроме того, в случае, когда String
имеет значение null
, будет выброшено исключение NullPointerException :
@Test(expected = NumberFormatException.class)
void givenInvalidString_whenUsingAs_thenThrowNumberFormatException() {
def invalidString = "123a"
invalidString as Integer
}@Test(expected = NullPointerException.class)
void givenNullString_whenUsingToInteger_thenThrowNullPointerException() {
def invalidString = null
invalidString.toInteger()
}
Чтобы этого не произошло, мы можем использовать метод isInteger
:
@Test
void givenString_whenUsingIsInteger_thenCheckIfCorrectValue() {
def invalidString = "123a"
def validString = "123"
def invalidNum = invalidString?. isInteger() ? invalidString as Integer : false
def correctNum = validString?.isInteger() ? validString as Integer : falseassertEquals(false, invalidNum)
assertEquals(123, correctNum)
}
9. Резюме
В этой короткой статье мы показали несколько эффективных способов переключения с объектов String
на объекты Integer
в Groovy.
Когда дело доходит до выбора наилучшего метода преобразования типа объекта, все вышеперечисленное одинаково хорошо. Самое главное — избежать ошибок, сначала проверив, может ли значение String
в нашем приложении быть нечисловым, пустым или нулевым
.
Как обычно, все примеры кода можно найти на GitHub .
Scala: Как преобразовать String в Int (Integer)
Часто задаваемые вопросы по Scala: Как преобразовать String
в Int
в Scala?
Решение: используйте toInt
Если вам нужно преобразовать String
в Int
в Scala, используйте метод toInt
, который доступен для объектов String
, например:
scala> val i = "1". toInt я: Целое = 1
Как видите, я просто привел строку "1"
в объект Int
с использованием метода toInt
, который доступен для любой строки
.
Однако имейте в виду, что это может привести к ошибке NumberFormatException
, как это происходит в Java:
scala> val i = "foo".toInt java.lang.NumberFormatException: для входной строки: "foo"
, поэтому вы захотите учесть это в своем коде, например, с оператором Scala try
/ catch
.
Java-подобная функция преобразования строки в целое число
Следующие функции показывают несколько способов обработки исключений, которые могут быть выброшены в процессе преобразования строки в целое число. В этом первом примере показан способ «Java» для записи функции преобразования String
в Int
:
def toInt(s: String): Int = { пытаться { s. toInt } ловить { случай e: Исключение => 0 } }
Эта функция возвращает правильное значение типа int, если строка может быть преобразована в тип int (например, «42»), и возвращает 0, если строка является чем-то другим, например строкой «foo».
Когда я говорю, что эта функция использует подход, подобный Java, обратите внимание, что изначально я написал эту статью до того, как в Java появился тип
Optional
.
Функция преобразования Scala «String to Int», использующая параметр
Более «подобный Scala» способ записи функции преобразования строки в int выглядит следующим образом:
def toInt(s: String): Option[Int] = { пытаться { Некоторые (s.toInt) } ловить { случай e: Исключение => Нет } }
Эта функция возвращает Some(Int)
, если строка успешно преобразована в целое число, и None
, если строку не удалось преобразовать в целое число. Эта функция показана в следующих примерах REPL:
scala> val x = toInt("foo") х: Опция[Int] = Нет scala> val x = toInt("10") х: Опция [Int] = Некоторые (10)
Как я писал в своей книге о Scala и функциональном программировании, вы также можете написать Scala toInt
функция, использующая Try
, Success
и Failure
, например:
импортировать scala.util. {Попытка, успех, неудача} def makeInt(s: String): Try[Int] = Try(s.trim.toInt)
Вы также можете вернуть Option
следующим образом:
импортировать scala.util.control.Exception._ def makeInt(s: String): Option[Int] = allCatch.opt(s.toInt)
См. мой учебник по идиомам Scala Option/Some/None, чтобы узнать больше о способах использования этих шаблонов и о том, как использовать Вариант
и Попробуйте результаты
.
этот пост спонсирован моими книгами: | |||
#1 Новый релиз | FP Бестселлер | Изучите Скала 3 | Быстро выучить FP |
Примечание. Как я уже упоминал выше, метод toInt
на самом деле не относится к классу String. На самом деле он содержится в классе с именем StringOps, который связан с классом String с помощью неявного преобразования в Scala. Я описываю это немного подробнее в статье Как показать методы String и StringOps в примерах Scala REPL.
Kotlin — преобразование строки в целое число
Преобразование строки в целое число в Kotlin
Чтобы преобразовать строку в целое число в Kotlin, используйте метод String.toInt() или Integer.parseInt(). Если строку можно преобразовать в допустимое целое число, любой из методов возвращает значение int.
Вам может понадобиться преобразовать строку в целое число в таких сценариях, как: извлечение чисел из строковых сообщений и выполнение над ними некоторых арифметических операций; вы получаете значение в виде строки извне вашей программы, но вы обрабатываете его как целое число в своем приложении; и т. д.
В этом уроке мы изучим различные способы преобразования строки в целое число и различные сценарии, в которых нам может понадобиться использовать это преобразование.
Синтаксис
Синтаксис String.toInt() приведен ниже.
String.toInt()
String.toInt() возвращает значение int, если преобразование прошло успешно. В противном случае создается исключение java.lang.NumberFormatException.
Синтаксис Integer.parseInt() приведен ниже.
Целое число.parseInt(String)
Функция Integer.parseInt() принимает строку в качестве аргумента и возвращает значение int, если преобразование прошло успешно. В противном случае выдается такое же исключение java.lang.NumberFormatException, как и в случае String.toInt().
Примеры
1. Преобразовать строку в целое с помощью String.toInt()
В этом примере мы сначала инициализируем строку. Во-вторых, мы вызываем toInt() для строки и сохраняем возвращенное значение int. Вы можете использовать это значение int в соответствии с вашими требованиями, но в этом примере мы просто печатаем его.
пример.kt
/** * Kotlin — преобразование Sting в Integer */ весело main(аргументы: Array) { //строка ул ул = "241" // преобразовать строку в целое число числовое значение = str.toInt() печать (число + 10) }
Запустите эту программу Kotlin. Просто чтобы доказать, что это целое число, мы добавляем к нему значение 10 и печатаем результат.
Вывод
251
2. Преобразование строки в целое число с помощью Integer.parseInt()
В этом примере мы сначала инициализируем строку. Во-вторых, мы вызываем Integer.parseInt() со строкой в качестве аргумента строки и сохраняем возвращенное значение int.
пример.kt
/** * Kotlin — преобразование Sting в Integer */ весело main(аргументы: Array) { //строка ул ул = "241" // преобразовать строку в целое число val число = Integer.parseInt (строка) печать (число + 10) }
Запустите эту программу Kotlin. Как и в предыдущем примере, мы добавляем значение 10 к целому числу и печатаем результат.
Выходные данные
251
3. Преобразование строки в целое — отрицательный сценарий
В этом примере мы попробуем преобразовать строку в целое число, где строка в целом не представляет допустимое целое число. Давайте посмотрим, что происходит. Конечно, str.toInt() выдает исключение.
пример.kt
/** * Kotlin — преобразование Sting в Integer */ весело main(аргументы: Array) { //строка ул ул = "241а" // преобразовать строку в целое число числовое значение = str.toInt() печать (число + 10) }
Запустите эту программу Kotlin, и вы получите следующий вывод.
Вывод
Исключение в потоке "main" java.lang.NumberFormatException: Для входной строки: "241a" в java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.