3.3 变量类型推断

3.3.1 省去变量类型

在Kotlin中大部分情况你不需要说明你使用对象的类型,编译器可以直接推断出它的类型。代码示例

1. fun typeInference(){
2. val str = "abc"
3. println(str)
4. println(str is String)
5. println(str::class)
6. println(str::class.java)

8. // abc
9. // true
10. // class java.lang.String (Kotlin reflection is not available)
11. // class java.lang.String

13. val d = Date()
14. println(d)
15. println(d is Date)
16. println(d::class)
17. println(d::class.java)

19. // Fri Jun 09 00:06:33 CST 2017
20. // true
21. // class java.util.Date (Kotlin reflection is not available)
22. // class java.util.Date

24. val bool = true
25. println(bool)
26. println(bool::class)
27. println(bool::class.java)

29. // true
30. // boolean (Kotlin reflection is not available)
31. // boolean

33. val array = arrayOf(1,2,3)
34. println(array)
35. println(array is Array)
36. println(array::class)
37. println(array::class.java)

39. // [Ljava.lang.Integer;@7b5eadd8
40. // true
41. // class [Ljava.lang.Integer; (Kotlin reflection is not available)
42. // class [Ljava.lang.Integer;
43. }

所以,我们只需要依据要产生的变量类型填写var或val,其类型通常能够被推断出来。编译器能够检测到其类型,自动地完成类型转换。当然,我们也可以明确地指定变量类型。

但是,类型推断不是所有的。例如,整型变量Int不能赋值Long变量。下面的代码不能通过编译:

1. fun Int2Long(){
2. val x:Int = 10
3. val y:Long = x // Type mismatch
4. }

我们需要显式地调用对应的类型转换函数进行转换:

1. fun Int2Long(){
2. val x:Int = 10
3. //  val y:Long = x // Type mismatch
4. val y: Long = x.toLong()
5. }

3.3.2 使用is运算符进行类型检测

is 运算符检测一个表达式是否某类型的一个实例。

如果一个不可变的局部变量或属性已经判断出为某类型,那么检测后的分支中可以直接当作该类型使用,无需显式转换:

1. fun getLength(obj: Any): Int? {
2. var result = 0
3. if (obj is String) {
4. // `obj` 在该条件分支内自动转换成 `String`
5. println(obj::class) //class java.lang.String
6. result = obj.length
7. println(result)
8. }
9. // 在离开类型检测分支后,`obj` 仍然是 `Any` 类型
10. println(obj::class) // class java.lang.Object
11. return result
12. }

测试类如下

1. @Test
2. fun testGetLength() {
3. val obj = "abcdef"
4. val len = variableVSValue.getLength(obj)
5. Assert.assertTrue(len == 6)

7. val obj2:Any = Any()
8. variableVSValue.getLength(obj2)
9. }