美文网首页Android
三、Kotlin 基本数据类型与类型系统

三、Kotlin 基本数据类型与类型系统

作者: Tenderness4 | 来源:发表于2018-01-22 22:56 被阅读0次
    1. 类型(type)本质上就是内存中的数值或变量对象的逻辑映射,也可以说是对较低层次的逻辑单元进行高层次的逻辑抽象。

      类型系统用于定义如何将编程语言中的数值表达式归类为许多不同的类型,如何操作这些类型,这些类型如何相互作用等。提供的主要功能有安全性、最优化、可读性、抽象化。下面针对安全性解释一下

      • 安全性

          "hello"+3//is right
          3+"hello"//is error,因为没有对Int的+进行重载
        
    2. Kotlin 是一门强类型的、静态类型、支持隐式类型的显示类型语言

      • 强类型语言在转换过程中需要显示调用
      • 静态类型检查是基于编译器来分析源码本身,能让很多bug在编码早期就被捕捉到,并优化运行
    3. 根类型Any

      和Java中的Object一样,区别是Object不包括基本类型:byte int long等,但是Kotlin直接统一,所有类型都是引用类型,统一继承父类Any

    4. 基本类型

      • 数字类型
        • 十进制:123

        • Long类型用大写L标记:123L

        • 十六进制:0x0F

        • 二进制:0b00001011

        • 不支持八进制

        • Kotlin对于数字没有隐式拓宽转换(例如Int不能隐式转成Long类型)

        • 显示转换

            val a:Int? = 1
            val b:Long? = a//error 不能隐式转换
            val b:Long? = a.toLong()//true
          
        • 每个数字类型都继承Number抽象类,定义了如下这些转换函数

            toDouble():Double
            toFloat():Float
            toLong():Long
            toInt():Int
            toChar():Char
            toShort():Short
            toByte():Byte
          
        • 运算符+重载

            缺乏隐式类型转换并不显著,因为类型会从上下文推断出来,而算术运算会有重载做适当转换,例如:
            
            ``` kotlin
            val l = 1L + 3 // Long + Int => Long
            ```
            
            这个是通过运算符`+`重载实现的。我们可以在Long类的源代码中看到这个`plus` 运算符函数的定义:
            
            ```
                public operator fun plus(other: Byte): Long
                public operator fun plus(other: Short): Long
                public operator fun plus(other: Int): Long
                public operator fun plus(other: Long): Long
                public operator fun plus(other: Float): Float
                public operator fun plus(other: Double): Double
            ```
            也就是说, 编译器会把`1L + 3` 翻译成 `1L.plus(3)`,然后这个传入的参数类型必须是Byte、Short、Int、Long、Float、Double中的一种。例如,我们传入一个字符`Char`参数,编译器就会直接抛错
            缺乏隐式类型转换并不显著,因为类型会从上下文推断出来,而算术运算会有重载做适当转换,例如:
            
            ``` kotlin
            val l = 1L + 3 // Long + Int => Long
            ```
            
            这个是通过运算符`+`重载实现的。我们可以在Long类的源代码中看到这个`plus` 运算符函数的定义:
            
            ```
                public operator fun plus(other: Byte): Long
                public operator fun plus(other: Short): Long
                public operator fun plus(other: Int): Long
                public operator fun plus(other: Long): Long
                public operator fun plus(other: Float): Float
                public operator fun plus(other: Double): Double
            ```
            也就是说, 编译器会把`1L + 3` 翻译成 `1L.plus(3)`,然后这个传入的参数类型必须是Byte、Short、Int、Long、Float、Double中的一种。例如,我们传入一个字符`Char`参数,编译器就会直接抛错
        * 运算
            
            
            Kotlin支持数字运算的标准集,运算被定义为相应的类成员(但编译器会将函数调用优化为相应的指令)。
            
            对于位运算,没有特殊字符来表示,而只可用中缀方式调用命名函数(`infix fun`),例如:
            
            ``` kotlin
            val x = (1 shl 2) and 0x000FF000
            ```
            
            这是完整的位运算列表(只用于 `Int` 和 `Long`):
            
            * `shl(bits)` – 有符号左移 (Java 的 `<<`)
            * `shr(bits)` – 有符号右移 (Java 的 `>>`)
            * `ushr(bits)` – 无符号右移 (Java 的 `>>>`)
            * `and(bits)` – 位与
            * `or(bits)` – 位或
            * `xor(bits)` – 位异或
            * `inv()` – 位非
            
            Kotlin支持数字运算的标准集,运算被定义为相应的类成员(但编译器会将函数调用优化为相应的指令)。
            
            对于位运算,没有特殊字符来表示,而只可用中缀方式调用命名函数(`infix fun`),例如:
            
            ``` kotlin
            val x = (1 shl 2) and 0x000FF000
            ```
            
            这是完整的位运算列表(只用于 `Int` 和 `Long`):
            
            * `shl(bits)` – 有符号左移 (Java 的 `<<`)
            * `shr(bits)` – 有符号右移 (Java 的 `>>`)
            * `ushr(bits)` – 无符号右移 (Java 的 `>>>`)
            * `and(bits)` – 位与
            * `or(bits)` – 位或
            * `xor(bits)` – 位异或
            * `inv()` – 位非
            
            Kotlin支持数字运算的标准集,运算被定义为相应的类成员(但编译器会将函数调用优化为相应的指令)。
            
            对于位运算,没有特殊字符来表示,而只可用中缀方式调用命名函数(`infix fun`),例如:
            
            ``` kotlin
            val x = (1 shl 2) and 0x000FF000
            ```
            
            这是完整的位运算列表(只用于 `Int` 和 `Long`):
            
            * `shl(bits)` – 有符号左移 (Java 的 `<<`)
            * `shr(bits)` – 有符号右移 (Java 的 `>>`)
            * `ushr(bits)` – 无符号右移 (Java 的 `>>>`)
            * `and(bits)` – 位与
            * `or(bits)` – 位或
            * `xor(bits)` – 位异或
            * `inv()` – 位非
        * 字符
    
            字符用 `Char` 类型表示。它们不能直接当作数字,但是它重载了对Int的plus方法
                
                kotlin
                    fun check(c: Char) {
                        if (c == 1) { // 错误:类型不兼容
                        // ……
                        }
                    }
    
    • Any?可空类型(Nullable Types)

      可空类型是Kotlin类型系统的一个特性,主要是为了解决Java中的令人头疼的
      NullPointerException问题。

      • null是Nothing?类型

          >>> "1"+null
          1null
                  
          >>> null+20
          null20
          
          >>> 20 +null //error 这是因为Int没有重载传入`null`参数的`plus()`函数。
        

        对null的话,你似乎能明白什么

      • 可空类型String?与安全调用?.

        我们来看一个例子。下面是计算字符串长度的简单Java方法:

            public static int getLength1(String str) {
                    return str.length();
            }
        
        
        我们已经习惯了在这样的Java代码中,加上这样的空判断处理:
        
        
            public static int getLength2(String str) throws Exception {
                    if (null == str) {
                        throw new Exception("str is null");
                    }
            
                    return str.length();
            }
            
        
        而在Kotlin中,当我们同样写一个可能为`null`参数的函数时:
        
    
            fun getLength1(str: String): Int {
                    return str.length
             }
        
        当我们传入一个`null`参数时:
        
    
        
            @Test fun testGetLength1() {
                val StringUtilKt = StringUtilKt()
                StringUtilKt.getLength1(null)
            }
        
        
        编译器就直接编译失败
    * kotlin.Unit类型
        
        Kotlin中的`Unit`类型实现了与Java中的`void`一样的功能。不同的是,当一个函数没有返回值的时候,我们用`Unit`来表示这个特征,而不是`null`。
    
        大多数时候,我们并不需要显式地返回`Unit`,或者声明一个函数的返回类型为`Unit`。编译器会推断出它。
    
            fun unitReturn() {
                return Unit
            }
        
            fun unitReturn(): Unit {
            }
            //  上述两种写法都是一样的
    *  kotlin.Nothing类型
    
        在Kotlin类型层次结构的最底层就是类型`Nothing
    
        正如它的名字Nothing所暗示的,`Nothing`是没有实例的类型
    
            >>> Nothing() is Any
            error: cannot access '<init>': it is private in 'Nothing'
            Nothing() is Any
            ^
    注意:Unit与Nothing之间的区别:  Unit类型表达式计算结果的返回类型是Unit。Nothing类型的表达式计算结果是永远不会返回的(跟Java
    

    中的void相同)。

        例如,throw关键字中断的表达式的计算,并抛出堆栈的功能。所以,一个`throw Exception` 的代码就是返回`Nothing`的表达式。代码示例:
    
            
            fun formatCell(value: Double): String =
                if (value.isNaN()) 
                    throw IllegalArgumentException("$value is not a number")  // Nothing
                else 
                    value.toString()
    
    1. 类型检测与类型转换
      • is

          val a:int = 1
          a is Int //true
        
      • instanceof

        str instanceof String,如果返回true,则str将拥有String类型的所有方法,相当于Java内的强制转换

      • as

        代码示例:

          >>> open class Foo
          >>> class Goo:Foo()
          >>> val foo = Foo()
          >>> val goo = Goo()
          
          
          >>> foo as Goo
          java.lang.ClassCastException: Line69$Foo cannot be cast to Line71$Goo
          
          >>> foo as? Goo
          null
          
          >>> goo as Foo
          Line71$Goo@73dce0e6
        

        我们可以看出,在Kotlin中,子类是禁止转换为父类型的。代码示例:

          >>> open class Foo
          >>> class Goo:Foo()
          >>> val foo = Foo()
          >>> val goo = Goo()
          
          
          >>> foo as Goo
          java.lang.ClassCastException: Line69$Foo cannot be cast to Line71$Goo
          
          >>> foo as? Goo
          null
          
          >>> goo as Foo
          Line71$Goo@73dce0e6
        

        我们可以看出,在Kotlin中,子类是禁止转换为父类型的。

    这一节主要是写Kt的数据类型,预热,下一节再介绍集合类

    相关文章

      网友评论

        本文标题:三、Kotlin 基本数据类型与类型系统

        本文链接:https://www.haomeiwen.com/subject/kjzraxtx.html