美文网首页
Kotlin的基础类型(二)

Kotlin的基础类型(二)

作者: 凌寒天下独自舞 | 来源:发表于2018-09-26 14:38 被阅读0次

Boolean型

布尔型只有一个 Boolean 型,用于表示逻辑上的“真”或“假”。与 Java 类似, Kotlin 的 Boolean类型的值只能是true或false,不能用0或者非0来代表。其他数据类型的值也不能转换成 Boolean型。
与前面介绍的数值型、Char类型类似的是,Boolean型的变量不能接受null值,Boolean? 类型的变量才能接受null值。Boolean类型将直接映射为 Java 的 boolean基本类型,但 Boolean? 类型将会映射成 boolean 的包装类: Boolean。

fun main(args: Array<String>) {
    var a: Boolean = true
    var b = false
    var c: Boolean
    c = true
    println("c的值为${c}")
}

null安全

null安全可以说是Kotiin语言对Java的重大改进之一,这样可以避免 Java编程时令人恐惧的NullPointerException (简称 NPE)

非空类型和可空类型

只有可空类型的变量或常量能接受null值,非空类型的变量或常量不可以。
对于可能发生“值缺失”的情况,编译器会自动推断该变量的类型为可空类型。
Kotlin对可空类型进行了限制 :如果不加任何处理,可空类型不允许直接调用方法、访问属性。因此,通过可空类型与非空类型的区分,KotIin即可在程序中避免空指针异常 。

fun main(args: Array<String>) {
    //由于str转换为Int有可能值缺失的情况,故 num1 有可能没有值,所以下面代码是错误的
    //var num1: Int = "111". toIntOrNull()
    //非空类型可接受空值
    var num2: Int? = "111". toIntOrNull()
    //编译器推断 n 的类型为 Int?
    var num3 = "1s1".toIntOrNull()

    var str: String? = "111"
    //可空类型不能直接调用属性或方法,因此下面代码是错误的
    //str.length
}

先判断后使用

可空类型的变量不允许直接调用方法或属性,但可以先判断该变量不为 null,然后再调用该变量的方法或属性。

    var str: String? = "111"
    var len = if (str != null) str.length else -1
    println("str的长度为${len}")
    str = null
    if (str != null && str.length > 0) {
        println("str的长度为${str.length}")
    } else {
        println("str是空字符")
    }
}

安全调用

fun main(args: Array<String>) {
    var str: String? = "111"
    //输出3
    println(str?.length)
    str = null
    //输出null
    println(str?.length)
}

上面程序中变量str的类型是 String?,因此程序使用了“?.”安全调用来访问str的length 属性,当b为 null时,程序也不会引发 NPE,而是返回 null。

此外,安全调用还可与 let全局函数结合使用

fun main(args: Array<String>) {
    //定义一个元素可为空的数组
    val myArr:Array<String?> = arrayOf("ss","111","qwer",null)
    for (item in myArr){
        //当item不为null是才调用let函数
        item?.let { println(it) }
    }
}

Elvis运算

Elvis运算也是一种小技巧,其实就是if else的简化写法。对比如下代码:

fun main(args: Array<String>) {
    var b:String? = "111"
    var len = if(b!=null) b.length else -1
    println(len)
    b=null

    //使用 Elvis 运算符
    var len2 = b?.length ?:-1
    println(len2)
}

“?:”运算符,该运算符就是 Elvis,它的含义是如果“?:”左边的表达式不为null,则返回左边表式的值,否则返回“?:”右边表达式的值。

由此可见,“?:”其实就是 if分支的简化写法。

强制调用

强制调用是为 NPE“爱好者”准备的,如果读者依然喜欢 Java那种简单、粗暴的方式: 不管变量是否为 null,程序都直接调用该变量的方法或属性。 Kotlin也为这种用法提供了支持 ,用“ !!.”即可强制调用可空变量的方法或属性,这样强制调用可能引发 NPE。例如如下代码:

fun main(args: Array<String>) {
    var b:String? = "111"
    println(b!!.length)
    b=null
    //引发空指针异常( NPE)
   // println(b!!.length)

    //定义一个元素可为空的数组
    val myArr:Array<String?> = arrayOf("ss","111","qwer",null)
    for (item in myArr){
        //引发空指针异常( NPE)
       // item!!.let { println(it) }
    }
}

字符串

Kotlin使用String代表字符串。字符串表示一个有序的字符集合,例如在前面代码中看到的 ”xq”、 ”sq”等代表字符串,字符串也可被当成多个字符的有序集合。

字符串类型

String类型是一种快速、现代化的字符串实现,字符串中的每一个字符都由独立的 Unicode 字符组成, String 允许通过形如s[i]的格式来访问字符串指定索引处的字符,也可通过for循环遍历字符串中的每一个字符。例如:

fun main(args: Array<String>) {
    var b: String = "qwert"
    //输出w
    println(b[1])
    //遍历
    for (str in b) {
        println(str)
    }

}

Kotlin 的字符串有两种字面值( Literal),分别如下。

  • 转义字符串: 转义字符串可以有转义字符,转义字符串很像 Java 字符串。
  • 原始字符串 :原始字符串可以包含转义字符和任意文本。转义字符不会被转义,原始字符串需要用 3个引号引起来 。
fun main(args: Array<String>) {
    //定义普通字符串
    var str = "xqsdsd"
    println(str.length)
    //定义原始字符串
    val bet = """
    |天上白玉京,
    |十二楼五城。
    |仙人抚我顶,
    |结发受长生。
    """.trimMargin()
    println(bet)
}

编程时考虑到程序格式,往往会在原始字符串中进行一些缩进, 但这些缩进并不是原始字符希望包含的,此时即可使用的trimMargin()方法来去掉原始字符串前面的缩进,在默认情况下,Kotlin使用竖线(|)作为边界符。也就是说,所有竖线之前的空白内容都会被去掉。如果有必要,开发者也可使用其他字符作为边界符,此时就需要在trimMargin()方法中传入该边界符作为参数。例如:

fun main(args: Array<String>) {
    //定义原始字符串
    val bet = """
    ^天上白玉京,
    ^十二楼五城。
    ^仙人抚我顶,
    ^结发受长生。
    """.trimMargin("^")
    println(bet)
}

字符串模板

Kotlin允许在字符串中嵌入变量或表达式,只要将变量或表达式放入 ${}中即可,这样 Kotlin将会把该变量或表达式的值嵌入该字符串中 。字符串模板不仅可以在普通字符串中使用,也可以在原始字符串中使用。例如:

fun main(args: Array<String>) {
    var bookPrice = 79
    println("图书的价格是${bookPrice}")
    val random = Random()
    println("随机数: ${random.nextInt(10)}")
    val text = """
        |图书的价格${bookPrice}
    """.trimMargin()
    println(text)
}

Kotlin字符串的方法

Kotlin的String与Java的String 并不是同一个类,因此它们的方法略有不同,但是这两个类所提供的功能大致相似。实际上Kotlin的String 类提供了更多的方法,如提供了一系列 toXxx()方法将字符串转换成数值,首字母大小写以及返回两个字符串相同的前缀、后缀的方法,还有 Java 的 String 的 contains()方法不支持使用正则表达式,但 Kotlin 的 String 的 contains() 方法支持使用正则表达式匹配。

fun main(args: Array<String>) {
    //转成数值类型
    var bookPrice: String = "79.1"
    println("double: ${bookPrice.toDouble()}")
    var intValue: String = "79"
    println("Int: ${intValue.toInt()}")


    var str: String = "dsadsa.com"
    //首字母大写
    println(str.capitalize())
    var str1: String = "DESdsdg.com"
    //首字母小写
    println(str1.decapitalize())

    //返回两个字符串相同的前缀
    println(str.commonPrefixWith("dsa.com"))
    //返回两个字符串相同的后缀
    println(str.commonSuffixWith("dsae.com"))
    var str3 = "java8898"
    //判断 str3 是否包含 3 个连续的数字
    println(str3.contains(Regex("\\d{3}")))
}

类型别名

Kotlin提供了类似于C语言中的 typedef的功能 : 可以为已有的类型指定另一个可读性更强的字。 Kotlin提供了 typealias 来定义类型别名。typealias 语句的语法格式为 :

typealias 类型别名=已有类型

如果类型名太长,我们可以使用较短的新名称来替代原类型名。这样有助于缩短较长的泛型。例如缩短集合类型,为内部类取一个更短的名字:

package test1

import java.io.File

//为 Set<Network . Node>指定更短的别名: NodeSet
typealias StrSet = Set<String>

//为 MutableMap<K, MutableList<File》指定更短的别名: F工leTable<K>
typealias FileTable<K> = MutableMap<K, MutableList<File>>

//为 A.Inner 内部类指定别名
typealias Ainner = A.Inner
//为 B.Inner 内部类指定别名
typealias Binner = B.Inner

fun main(args: Array<String>) {
    //使用命名变量
    var s: StrSet
    var f: FileTable<StrSet>
    var a = A().Ainner()
    var b = B().Binner()
}

class A {
    inner class Inner 
}

class B {
    inner class Inner
}

相关文章

网友评论

      本文标题:Kotlin的基础类型(二)

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