上一篇文章我们学习了Kotlin基本类型(一)
其中有整型、浮点数和字符。如果不懂的可以去上篇文章进行查看
Boolean类型
- 布尔型只有true和false在kotlin中,不能使用0或者非0来代表。其他的数据值也是不能转换成Boolean的
- 虽然字符串不能转换成Boolean类型。但是Boolean类型可以插在字符串中
fun initBoolean(){
val a: Boolean = true
val b: Boolean = false
println("$a , $b")
}
# true , false
- 在kotlin中,Boolean类型使用在if,while,do-while中。
- 与前面介绍的整数类型个Char类型一样,Boolean是不接受null的,但是Boolean?是可以接受null值得。Boolean类型将直接映射成为java中的boolean基本类型。Boolean?类型将直接映射成为java中的Boolean的包装类
fun useBoolean(){
val a: Int = 1
// if (a){
//
// }
//上面这是错误的
if (a == 1) {
}
}
null安全
- null安全可以说是Kotlin语言对java的重大改进了,这样避免java中的NullPointException。
非空类型和可空类型
fun isNullType(){
val str: String = "number"
//不可以使用Int来申明
// val a: Int = str.toIntOrNull()
val b: Int? = str.toIntOrNull()
// println(a)
println(b)
}
# null
- 对比上面的两行重要的代码:第一行代码声明为Int,第二行声明为Int?。程序的第一行是无法提供编译的,因为不接受null。第二行可以通过编译,其中Int?为可空类型,这种类型的变量可以接受Int值和null;而Int类型只接受Int值,不能接受null
- 对于可能发生的“值缺失”的情况,编译器会自动推断该变量的类型为可空变量
val a = str.toIntOrNull()
需要指出的是,只有可空类型的变量或常量才能接受null,非空类型的变量和常量是无法接受null的
- kotlin对可空类型进行了限制:如果不加任何的限制,可空类型的变量是不可以调用其方法和属性的
fun accessMethod(){
var str1: String = "zhang"
var str2: String? = "zhang"
// str1为非空变量,不能接受null值
// str1 = null
// str2为可空变量, 可以接受null值
// str2 = null
//str1为非空变量,所以不会出现空指针的现象
println(str1.length)
//str为可空变量,不能直接进行调用变量的方法和属性
// (可以先判断是否为null,安全调用或强制调用来调用方法和属性)
println(str2.length)
}
先判断后使用
- 可空变量类型不允许直接调用方法和属性,但是可以先判断变量是否为null,然后在调用该变量的方法和属性
fun okNullAccess(){
var a: String? = "zhang"
val len = if (a != null) a.length else -1
println(len)
a = null
if (a != null && a.length > 0){
println(a.length)
}
}
- 上面的程序,虽然可空变量类型不允许调用变量的方法和函数。Kotlin要求我们可以进行判断不为null,然后调用方法和函数
安全调用
user?.dag?.name
- 例如上面的一行代码。这段代码表示如果user不为空,则返回user的dog属性;如果dog属性值不为null,则继续获取dog属性值得name属性。反过来,如果user为null,或者user.dag为null,那么整个表达式将会返回为null。Kotlin中的安全调用和这个也是类似的
fun safeCall(){
var a: String? = "kotlin"
// println(a.length) //这是不正确的,可空变量不允许直接调用方法和属性
println(a?.length)
a = null
println(a?.length)
}
# 6
# null
- 上面代码申请了一个可空的String。我们使用了安全调用。使用安全调用来查看变量a的lenght方法。即使a为null,那么也不会发生空指针,而是返回null
- kotlin的安全调用也是支持链式的
- 安全调用还可以和let全局函数结合使用
fun safeLineCall(){
val arr: Array<String?> = arrayOf("zhao", "qian", null, "sun")
for (item in arr){
item?.let { println(it) }
}
}
- 上面代码使用安全调用let函数,这样只有当item元素不为null是才会进行调用。里面传入了一个lambda表达式作为参数
Elvis运算
- 这是一种技巧,相当于简化了if else写法
fun elvisAccess(){
val s: String? = "kotlin"
val len = if (s != null) s.length else -1
val len1 = s?.length?: -1
println(len)
println(len1)
}
# 6
# 6
- 第一种使用了传统的if else语句。重点是第二句,使用了Elvis。首先使用了安全调用来访问变量的lenght属性。当?:左边为空时,返回右边的表达式,当左边的表达式不为空时,返回左边的表达式。既然右边是表达式,那么就可以使用报错的信息
val len1 = s?.length ?: throw NumberFormatException()
强制调用
fun mandatory(){
val a: String? = "Kotlin"
println(a.length)
println(a!!.length)
}
- 强制调用和java差不多
字符串
- 字符串就是字符的有序集合
- String类型是一种快速、现代化的字符串实现,字符串中的每一个字符都有独立的Unicode字符组成,String允许使用形如s[i]的格式来访问字符串指定索引处的字符串,也可以使用for循环
fun findCharFromString(){
val a: String = "kotlin"
println(a[2])
for (i in a){
println(i)
}
}
- Kotlin的字符串有两种字面值,分别如下:
- 转义字符串:转移字符串可以有转义字符,很像java中的
- 原始字符串:原始字符串可以包含换行和任意文本。原始字符串需要用3个引号引起来
fun stringTemplate(){
val a = "kotlin"
val b = """
黄河
长江
""".trimIndent()
println(a)
println(b)
}
# kotlin
# 黄河
# 长江
fun stringTemplate(){
val a = """
黄河
长江
""".trimMargin()
val b = """
|黄河
|海沧将
""".trimMargin()
val c = """
^黄河
^长江
""".trimMargin("^")
println(a)
println(b)
println(c)
}
# 黄河
# 长江
# 黄河
# 海沧将
# 黄河
# 长江
# trimMargin的作用是删除前面的空格,默认是|前面的。也可以在方法里面以参数的形式进行指定
字符串模板
- kotlin允许在字符串中嵌入变量或表达式,只要将变量或表达式放入${}中即可,这样kotlin将会把变量或表达式的值嵌入该字符串中
- 字符串模板不仅可以在普通字符串中使用,也可以在原始字符串中使用
fun insertValue(){
val a = "MainActivity"
val resultA = "$a, ${a.javaClass}"
val resultB = """
$a
${a.javaClass}
""".trimIndent()
println(resultA)
println(resultB)
}
# MainActivity, class java.lang.String
# MainActivity
# class java.lang.String
字符串的方法
fun stringmethod(){
val a: String? = "baidu.com"
val b: String? = "google.com"
val c: String? = "java789"
println(a?.capitalize()) //首字母大写
println(a?.decapitalize()) //首字母小写
println(a?.commonPrefixWith("baidu.com")) //返回相同的前缀
println(b?.let { a?.commonSuffixWith(it) }) //返回相同的后缀
println(c?.contains(Regex("\\d{3}"))) //和java不一样的是,这个方法支持正则表达式
}
类型别名
- 和C语言中的typedef的功能类似,kotlin中的关键字是typealias
typealias str = String
fun alias(){
val a: str = "zhang"
}
class A{
inner class Inner
}
class B{
inner class Inner
}
typealias AInner = A.Inner
typealias BInner = B.Inner
fun aliasOther(){
val a: AInner = A().Inner()
val b: BInner = B().Inner()
}