Kotlin的基础类型(二)

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()
    //编译器推断的类型为 Int?
    var num3 = "11".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
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容