- Преобразование типов данных в Kotlin
- Содержание статьи
- Операции со смешанными типами в Kotlin
- Вывод типов данных в Kotlin (Type inference)
- Вопросы для проверки
- Как работает синтаксис доступа к свойствам Kotlin для классов Java (т.е. EditText setText)?
- Type mismatch: inferred type is String? but String was expected #96
- Comments
- shofizone commented Feb 15, 2021
- dvaldivia commented Feb 23, 2021
- devshisiyani commented Mar 3, 2021
- YazeedAlKhalaf commented Mar 4, 2021
- dvaldivia commented Mar 4, 2021
- shofizone commented Mar 4, 2021 •
- lovemory commented Apr 29, 2021
- 5244santila commented May 4, 2021
- anhdhq commented May 20, 2021
- impliesiOS commented May 26, 2021
Преобразование типов данных в Kotlin
Иногда данные из одного формата требуется преобразовать в другой. В данной статьей мы рассмотрим способы конвертирования типа данных.
Содержание статьи
Обратите внимание, что попытка выполнить конвертацию типа следующим образом обернется ошибкой:
Текст ошибки, которую выдает Kotlin при попытке выполнить преобразование таким образом:
Некоторые языки программирования менее строгие и выполняют конвертацию подобного рода автоматически. Опыт показывает, что такое автоматическое преобразование является источником ошибок в программах и зачастую снижает производительность.
Kotlin запрещает присваивать значение одного типа другому и тем самым помогает избежать проблем.
Помните, что именно программисты заставляют компьютеры работать. В Kotlin частью задачи разработчика является явное преобразование типов. Если вам нужно преобразование, вы должны сообщить программе об этом сами!
Вместо простого присваивания требуется явно сообщить о необходимости преобразования типа. Это делается следующим образом:
Теперь присваивание однозначно сообщает Kotlin, что вы хотите преобразовать исходный тип Double в новый тип Int .
На заметку: В данном случае присваивание десятичного значения целому числу приводит к потере точности: переменная integer получает значение 12 вместо 12.5 . Именно по этой причине важно работать явно. Kotlin хочет убедиться, что вы знаете, что делаете, и что вы можете потерять данные, выполняя преобразование типов.
Операции со смешанными типами в Kotlin
До сих пор вы видели только операторы, действующие независимо от целых или десятичных чисел. Но что, если у вас есть целое число, которое требуется умножить на десятичное?
У вас может возникнуть идея сделать что-то вроде этого:
В данном примере константа hoursWorked явно конвертируется в тип Double для совпадения с типом константы hourlyRate . Однако, делать это нет нужды. Kotlin позволяет умножать эти значения без всякой конвертации следующим образом:
В Kotlin оператор * можно использовать со смешанным типам . Это правило также применяется к другим арифметическим операторам. Несмотря на то, что hoursWorked является типом Int , это не повлияет на точность hourlyRate . Результатом все равно будет 195.0 !
Kotlin старается быть как можно более кратким и пытается вывести ожидаемое поведение, когда это возможно. Таким образом, вы тратите меньше времени на заботу о типах и больше на создание интересных программ!
Вывод типов данных в Kotlin (Type inference)
До сих пор каждое объявление переменной или константы сопровождалась объявлением типа. Может возникнуть вопрос, зачем писать : Int и : Double , ведь правая часть присваивания уже является Int или Double . Разумеется, это излишне, это ведь и так понятно.
Оказывается, компилятору Kotlin это тоже понятно. Ему не нужно постоянно указывать тип — он может определить его самостоятельно. Это делается с помощью процесса, который называется выводом типа. Это ключевой компонент мощности Kotlin, который есть далеко не в каждом языке программирования.
Таким образом, вы можете просто не указывать тип в большинстве мест, где вы его видите.
К примеру, рассмотрим следующее объявление константы:
Иногда будет полезно проверить предполагаемый тип переменной или константы. Вы можете сделать это в IntelliJ, нажав на название переменной или константы и удерживая клавиши Control + Shift + P. IntelliJ отобразит всплывающее окно, наподобие следующего:
IntelliJ показывает предполагаемый тип, предоставляя вам объявление, которое вам пришлось бы использовать, если бы не было вывода типа (type inference). В данном случае это тип Int .
Для других типов это также работает:
При удерживании клавиш Control + Shift + P будет показано следующее:
Из данных примеров видно, что в выводе типов никакой магии нет. Kotlin просто делает то же самое, что и ваш мозг. Языки программирования без вывода типов часто могут показаться многословными, потому что зачастую нужно указывать очевидный тип каждый раз при объявлении переменной и константы.
На заметку: В следующих уроках вы узнаете о более сложных типах данных, для которых Kotlin не всегда может определить тип автоматически. Однако это довольно редкий случай, вывод типа используется для большинства примеров кода данного курса — за исключением случаев, когда вы хотите указать тип самостоятельно.
В некоторых случаях требуется определить константу или переменную и убедиться в их типе, даже если вы назначаете другой тип. Ранее вы видели, как можно преобразовать один тип в другой. Например, рассмотрим следующий пример:
Здесь Kotlin выберет Int в качестве типа константы wantADouble . Однако, что если вам нужен вместо Int тип Double ?
Сначала требуется сделать следующее:
Это похоже на преобразование типа, которое вы видели ранее.
Другой опцией стал бы отказ от использования вывода типов вообще:
Быть может, вам захочется сделать следующее:
Этого делать нельзя, компилятор выведет следующую ошибку: The integer literal does not conform to the expected type Double .
На заметку: В Kotlin литеральные значения, такие как 3 , имеют определенный тип — Int . Если вы хотите преобразовать их в другой тип, вы должны сделать это явно, например, вызвав toDouble() . Литеральное числовое значение, содержащее десятичную точку, может использоваться только как Double и должно быть явно преобразовано, если вы хотите использовать его как что-то еще. По этой причине нельзя присвоить значение 3 константе actualDouble .
Точно так же литеральные числовые значения, которые содержат десятичную точку, не могут быть целыми числами integer. Это означает, что вы могли бы избежать всего этого обсуждения, если бы начали со строчки:
val wantADouble = 3.0
Вопросы для проверки
1. Создайте константу под названием age1 , которая равна 42 . Создайте константу age2 , которая равна 21 . Проверьте, используя Control + Shift + P , что тип обоих был правильно выведен как Int ;
2. Создайте константу avg1 , ее значением должно быть среднее арифметическое age1 и age2 , которое находится через простую операцию (age1 + age2) / 2 . Используйте Control + Shift + P, чтобы проверить тип и проверить результат avg1 . Что не так?
3. Исправьте ошибку в приведенном выше упражнении, преобразовав age1 и age2 в тип Double . Используйте Control + Shift + P, чтобы проверить тип и результат avg1 . Почему теперь все правильно?
Источник
Как работает синтаксис доступа к свойствам Kotlin для классов Java (т.е. EditText setText)?
Я пытаюсь переключить свой проект Android на Kotlin. У меня есть EditText (подкласс TextView ), для которого я хочу установить подсказку и текст программно. Подсказка работает как положено. Для текста, однако, я получаю исключение несоответствия типов, если я пытаюсь сделать это, используя синтаксис Kotlin:
Если мы посмотрим на объявление, мы найдем идентичные подписи, унаследованные от TextView :
У меня сложилось впечатление, что xy = z было сокращением для x.setY(z) но, очевидно, это впечатление было неправильным. setText() рассматривается как обычный метод, а не как установщик, но какая разница между этими двумя методами, которая заставляет компилятор вести себя по-разному? Единственное, о чем я могу подумать, это то, что TextView имеет свойство mHint но я не думаю, что это может иметь место.
Еще одна вещь, которую я не совсем понимаю: откуда взялся android.text.Editable ? Нет соответствующего метода setText(Editable) и нет открытого поля этого типа.
При генерации синтетического свойства пары Java getter/setter Kotlin сначала ищет геттер. Геттера достаточно, чтобы создать синтетическое свойство с типом геттера. С другой стороны, свойство не будет создано, если присутствует только сеттер.
При запуске сеттера создание свойства становится более сложным. Причина в том, что геттер и сеттер могут иметь различный тип. Более того, геттер и/или сеттер могут быть переопределены в подклассе.
В вашем случае класс TextView содержит getter CharSequence getText() и setter void setText(CharSequence) . Если у вас есть переменная типа TextView , ваш код будет работать нормально. Но у вас есть переменная типа EditText . И класс EditText содержит переопределенный getter Editable getText() , что означает, что вы можете получить Editable для EditText и установить Editable в EditText . Поэтому Котлин разумно создает синтетическое свойство text типа Editable . Класс String не является Editable , поэтому вы не можете назначить экземпляр String для свойства text класса EditText .
Чтобы избежать несоответствия типов, вы можете использовать внутренний класс Factory класса Editable.
Итак, теперь вы можете сделать что-то вроде:
В качестве альтернативы вы можете написать расширение:
Затем вы можете использовать его как таковой:
android.text.Editable происходит от getText() . Мне кажется, что разрешение obj.text = value в Котлине – двухэтапный процесс.
- Компилятор пытается найти свойство text или метод Java getText , из которого он выводит тип свойства
- Для свойства inferred type компилятор пытается найти соответствующий набор свойств или метод Java setText(PropertyType value)
Источник
Type mismatch: inferred type is String? but String was expected #96
Comments
shofizone commented Feb 15, 2021
gallery_saver-2.0.3\android\src\main\kotlin\carnegietechnologies\gallery_saver\FileUtils.kt: (280, 35): Type mismatch: inferred type is String? but String was expected
FAILURE: Build failed with an exception.
- What went wrong:
Execution failed for task ‘:gallery_saver:compileDebugKotlin’.
Compilation error. See log for more details
Try:
Run with —stacktrace option to get the stack trace. Run with —info or —debug option to get more log output. Run with —scan to get full insights.
BUILD FAILED in 25s
Exception: Gradle task assembleDebug failed with exit code 1
The text was updated successfully, but these errors were encountered:
dvaldivia commented Feb 23, 2021
devshisiyani commented Mar 3, 2021
YazeedAlKhalaf commented Mar 4, 2021
@CarnegieTech Any plans to fix this?
dvaldivia commented Mar 4, 2021
I believe this is due to the null safety changes that are incoming, one we migrate out apps to null safety this problem will not matter
shofizone commented Mar 4, 2021 •
No response form author. This error is coming from native android part -> Kotlin. I have a simple fix for this problem, try this https://github.com/shofizone/gallery_saver.git
Use it as a override dependency form git, until author publish a new update.
lovemory commented Apr 29, 2021
pubspec.yaml
gallery_saver: ^2.1.0
image_picker: ^0.7.4
e: F:\flutter.pub-cache\hosted\pub.flutter-io.cn\gallery_saver-2.1.0\android\src\main\kotlin\carnegietechnologies\gallery_saver\FileUtils.kt: (279, 35): Type mismatch: inferred type is String? but String was expected
e: F:\flutter.pub-cache\hosted\pub.flutter-io.cn\gallery_saver-2.1.0\android\src\main\kotlin\carnegietechnologies\gallery_saver\FileUtils.kt: (282, 35): Type mismatch: inferred type is String? but String was expected
FAILURE: Build failed with an exception.
- What went wrong:
Execution failed for task ‘:gallery_saver:compileDebugKotlin’.
Compilation error. See log for more details
Try:
Run with —stacktrace option to get the stack trace. Run with —info or —debug option to get more log output. Run with —scan to get full insights.
BUILD FAILED in 34s
5244santila commented May 4, 2021
I have the same issue. When attempting to revert to earlier stable versions, the null stability causes more trouble with other dependencies in my code.
anhdhq commented May 20, 2021
I’m trying to save images and videos after take them from the camera to the device.
camera: ^0.8.1
video_player: ^2.1.1
gallery_saver: ^2.1.0
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\gallery_saver-2.1.0\android\src\main\kotlin\carnegietechnologies\gallery_saver\FileUtils.kt: (279, 35): Type mismatch: inferred type is String? but String was expected
e: C:\flutter.pub-cache\hosted\pub.dartlang.org\gallery_saver-2.1.0\android\src\main\kotlin\carnegietechnologies\gallery_saver\FileUtils.kt: (282, 35): Type mismatch: inferred type is String? but String was expected
FAILURE: Build failed with an exception.
- What went wrong:
Execution failed for task ‘:gallery_saver:compileDebugKotlin’.
Compilation error. See log for more details
Try:
Run with —stacktrace option to get the stack trace. Run with —info or —debug option to get more log output. Run with —scan to get full insights.
BUILD FAILED in 3s
Running Gradle task ‘assembleDebug’.
Running Gradle task ‘assembleDebug’. Done 4.4s
Exception: Gradle task assembleDebug failed with exit code 1
impliesiOS commented May 26, 2021
Launching lib/main.dart on POCO F1 in debug mode.
Running Gradle task ‘assembleDebug’.
e: /Users/imac/Documents/K_Flutterr/flutter/.pub-cache/hosted/pub.dartlang.org/gallery_saver-2.1.0/android/src/main/kotlin/carnegietechnologies/gallery_saver/FileUtils.kt: (279, 35): Type mismatch: inferred type is String? but String was expected
e: /Users/imac/Documents/K_Flutterr/flutter/.pub-cache/hosted/pub.dartlang.org/gallery_saver-2.1.0/android/src/main/kotlin/carnegietechnologies/gallery_saver/FileUtils.kt: (282, 35): Type mismatch: inferred type is String? but String was expected
FAILURE: Build failed with an exception.
- What went wrong:
Execution failed for task ‘:gallery_saver:compileDebugKotlin’.
Compilation error. See log for more details
Try:
Run with —stacktrace option to get the stack trace. Run with —info or —debug option to get more log output. Run with —scan to get full insights.
BUILD FAILED in 4s
Exception: Gradle task assembleDebug failed with exit code 1
in iOS its Works Perfectly But in android, it’s Gate Same Issue Any idea to solve It? Thanks In Advance
Источник