2、基本数据类型:数字篇 上

作者: 萧文翰 | 来源:发表于2020-01-17 13:16 被阅读0次

    基本数据类型

    这节课我们先来看看 Kotlin 中都有哪些基本数据类型。

    一切皆对象

    和 Java 不同,在 Kotlin 的世界中,一切皆为对象。基本数据类型会被自动装箱成对象(但不支持拆箱),都可以访问成员函数和属性。

    基本类型

    在 Kotlin 中,总共有5种基本数据类型,他们分别是数字、字符、布尔、数组和字符串。

    数字

    和常见的高级编程语言类似,在 Kotlin 中,对于数字的表示,有整数和浮点(小数)之分。

    整数

    Kotlin 提供了4种方式来表示整数,它们所占的大小各有不同,取值范围也会随之变化,下表列出了4种整数类型的详细情况:

    类型 大小(bits) 最小值 最大值
    Byte 8 -128 127
    Short 12 -32768 32767
    Int 32 -2147483648 2147483647
    Long 64 -9223372036854775808 9223372036854775807

    默认情况下,在赋值时,只要数值未超过 Int 的取值范围,Kotlin 都会将其推断为 Int 类型。否则,会推断为 Long 类型。当然,我们也可以在赋值时加上“L”后缀,以显式指定变量为 Long 型。
    此外,Kotlin 还支持 16 进制和 2 进制的数值表示法。当要表示 16 进制时,其值以“0x开头”;当要表示 2 进制时,其值以“0b”开头;8 进制在 Kotlin 中是不被支持的。
    为了阅读方便,自 Kotlin 1.1 起,我们可以给数字添加下划线,以增强数值的可读性。
    以下是一些例子:

    // byte 类型
    val byteSample = 1
    // int 类型
    val intSample = 1
    // long 类型
    val longSample = 1L
    // 将自动转为 long 类型
    val autoToLong = 1000000000
    // 16 进制表示法
    val hexSample = 0xFF
    // 2 进制表示法
    val binSample = 0b00001011
    // 使数值更易读的下划线表示
    val bankCardNum = 4367_4200_6458_0486_097L
    

    浮点数

    Kotlin 提供了两种类型用来表示浮点值,即单精度和双精度。和整数类似,这两种类型大小不同,表示的数值范围也有所差异,具体见下表:

    类型 大小(bits) 有效数字比特数 指数比特数 十进制位数
    Float 32 24 8 6-7
    Double 64 53 11 15-16

    默认情况下,在赋值时,编译器会默认按照 Double 类型初始化浮点变量。如果我们需要将一个变量显式指定为 Float 类型,需要在值后面加上“F”(大小写皆可) 后缀。特别注意:显式指定时,超过 Float 范围的部分将丢失精度,末位会四舍五入。
    参考下面的代码示例:

    // double 类型
    val doubleSample = 1.2
    // double 类型
    val doubleSample2 = 1.234e10
    // float 类型
    val floatSample = 1.2F
    // 丢失精度的转换
    // 实际值将变为:3.1415927
    val fPi = 3.1415926535898F
    // 实际值将变为:1.1234568
    val fTest = 1.123456789F
    

    隐式转换与显示转换

    Kotlin 并不支持类型“隐式拓宽转换”。
    何为隐式拓宽转换呢?

    fun main(args: Array<String>){
        val intSample = 1;    
        fun doubleOutput(doubleSample: Double){        
            println(doubleSample)    
        }    
        doubleOutput(intSample)
    }
    

    上面这段代码中,首先定义了一个值为1的数字变量 intSample,随后实现了一个名为 doubleOutput() 的方法。现在我们还没学过“方法”,不过没关系,我们暂且将其理解成需要一个浮点(Double)类型变量的事物。随后,我们调用了这个方法,将 intSample 的整数类型值交给它。
    大家猜猜看,运行这段代码,会有怎样的结果呢?
    想好了吗?
    答案是:这段代码根本无法正常运行!
    结合之前的知识,我们知道,intSample 将会默认成为一个 Int 类型的变量,而 doubleOutput() 方法需要一个浮点 Double 类型。Kotlin 并不支持自动隐式由 Int -> Double 类型的变换。所以语法错误,代码无法运行。这一点和 Java 是完全不同的,如果您之前一直使用 Java 编程语言,要特别注意这一点。
    现在,请思考:如果将上述代码改为:

    fun main(args: Array<String>){
        val intSample = 1f;    
        fun doubleOutput(doubleSample: Double){        
            println(doubleSample)    
        }    
        doubleOutput(intSample)
    }
    

    如此修改,代码可以运行吗?如果可以的话,运行结果会是怎样的呢?
    答案是——代码依旧无法运行,因为 Float 无法隐式转为 Double。
    再来思考,阅读下面的代码片段:

    fun main(args: Array<String>) {   
        val result = 1L + 2;    
        println(result)
    }
    

    问题:这段代码可以运行吗?运行结果是多少呢?
    答案是:这段代码可以运行,运行结果为3。最终,result 类型为Long。
    如何理解呢?
    变量 result 最终的类型是根据上下文推断出来的。代码中,存在算术运算符(我们以后会讲到),这一操作中,隐式地完成了类型转换,即:
    Long + Int => Long, 算术运算符会有重载做合适的类型转换。
    那么,除了算术运算符,有没有办法完成类型转换呢?
    答案是肯定的,即显式转换。
    在 Kotlin 中,每个数字类型都支持以下几种方式的显式转换:

    1. toByte()
    2. toShort()
    3. toInt()
    4. toLong()
    5. toFloat()
    6. toDouble()
    7. toChar()

    很容易理解:toxxx(),即表示转换到xxx类型。
    举个例子:我们知道,下面这段代码是无法正常运行的:

    fun main(args: Array<String>){
        val intSample = 1;    
        fun doubleOutput(doubleSample: Double){        
            println(doubleSample)    
        }    
        doubleOutput(intSample)
    }
    

    但是,我们可以借助显式转换,将 intSample 转换成 Double 类型。就可以正常编译运行了!

    fun main(args: Array<String>){
        val intSample = 1;    
        fun doubleOutput(doubleSample: Double){        
            println(doubleSample)    
        }    
        doubleOutput(intSample.toDouble())
    }
    

    仔细对比上面两段代码,并运行修改过的代码,其结果为:1.0,类型为 Double。

    相关文章

      网友评论

        本文标题:2、基本数据类型:数字篇 上

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