Kotlin学习系列——智能转换

深藏阁楼爱情的钟 2023-06-29 05:36 82阅读 0赞

官方文档: http://kotlinlang.org/docs/reference/typecasts.html

1.is和!is操作符(Operators)

  1. 在运行时,可用is或!is操作符来检查对象类型是否符合要求:
  2. if (obj is String) {
  3. print(obj.length)
  4. }
  5. if (obj !is String) { //等价于 !(obj is String)
  6. print("Not a String")
  7. }else {
  8. print(obj.length)
  9. }
  10. 1
  11. 2
  12. 3
  13. 4
  14. 5
  15. 6
  16. 7
  17. 8
  18. 9
  19. 10

2.智能转换(Smart Casts)

  1. java不同,Kotlin一般不需要显式转换对象类型,
  2. 因为对于不可变的值,编译器能跟踪is检查类型,在需要时会自动插入类型转换代码(安全):
  3. fun demo(x: Any) {
  4. if (x is String) {
  5. print(x.length) //编译器自动把x转换为String类型
  6. }
  7. }
  8. 1.智能转换的例子
  9. kotlin编译器足够聪明,能识别反向检查类型!is操作符,会自动插入类型转换代码:
  10. if (x !is String) return
  11. print(x.length) //编译器自动把x转换为String类型:
  12. // ||右侧, x自动转换为String类型
  13. if (x !is String || x.length == 0) return
  14. // &&右侧, x自动转换为String类型
  15. if (x is String && x.length > 0) {
  16. print(x.length) // x 自动转换为字符串
  17. }
  18. //智能转换(smart casts)也用于when表达式和while循环
  19. when (x) {
  20. is Int -> print(x + 1)
  21. is String -> print(x.length + 1)
  22. is IntArray -> print(x.sum())
  23. }
  24. 2.智能转换的适用条件
  25. 如果不能保证变量在类型检查is/!is操作符和变量使用之间不可改变时,智能转换不能用!
  26. 智能转换的适用条件/规则:
  27. val局部变量-总是适用!
  28. val属性-适用于privateinternal,或者类型检查is/!is在声明属性的同一模块中执行;
  29. 不适用于open的属性,或者具有自定义getter的属性!
  30. var局部变量—适用于变量在类型检查和使用之间没有修改,且不在修改它的lambda中捕获!
  31. var属性-不适用(因为该变量可随时被修改)
  32. 1
  33. 2
  34. 3
  35. 4
  36. 5
  37. 6
  38. 7
  39. 8
  40. 9
  41. 10
  42. 11
  43. 12
  44. 13
  45. 14
  46. 15
  47. 16
  48. 17
  49. 18
  50. 19
  51. 20
  52. 21
  53. 22
  54. 23
  55. 24
  56. 25
  57. 26
  58. 27
  59. 28
  60. 29
  61. 30
  62. 31
  63. 32
  64. 33
  65. 34
  66. 35
  67. 36

3.不安全转换-操作符as

  1. 如果类型不可能转换,转换操作符会抛出异常,称为不安全转换!
  2. Kotlin不安全转换就是中缀操作符as,例如:
  3. val y = null
  4. //kotlin类型默认不能为空(null),as会抛出异常TypeCastException
  5. val x: String = y as String
  6. //必须在转换右边添加?,表示可空(null)类型:
  7. val x: String? = y as String?
  8. 1
  9. 2
  10. 3
  11. 4
  12. 5
  13. 6
  14. 7
  15. 8

4.安全(可空)转换-操作符as?

  1. 为避免抛出异常,可用安全转换操作符as?,在失败时返回null
  2. val x: String? = y as? String
  3. 尽管as?右边是一个非空类型String,但是as?转换失败时返回可空(null)
  4. 说白了就是,as?函数参数String不能为null,但是as?函数的返回值可以是null
  5. 1
  6. 2
  7. 3
  8. 4
  9. 5

5.类型转换异常

我们都知道在 Java 中如果强制类型转换出错,那么程序就会崩溃报错类型转化异常,那么如果我们写错了会怎么样呢?将上面的代码故意改错,定义 parent 为 Parent 类型的,代码如下:

  1. //创建父类 Parent
  2. open class Parent
  3. //创建子类 Child
  4. class Child:Parent(){
  5. val name:String = "张三"
  6. }
  7. fun main(args: Array<String>) {
  8. //智能强制类型转化
  9. val parent:Parent = Parent()
  10. if (parent is Child){
  11. println(parent.name)
  12. }
  13. }

运行之后发现,程序没有抛出异常,但是也什么都没有打印;可以看出来在 Kotlin 中,即使我们写错了,也不会导致程序崩溃。

6. Kotlin 智能类型转换总结

写法:先加判断再写逻辑,如: if (parent is Child) println(parent.name)
优点:不会抛出类型转换异常

发表评论

表情:
评论列表 (有 0 条评论,82人围观)

还没有评论,来说两句吧...

相关阅读