连载 | Kotlin Primer· 第二章 · 基本语法

171 阅读5分钟
原文链接: mp.weixin.qq.com


作者:张涛 (沪江Android开发工程师)
本文原创,转载请注明作者及出处。

kotlin的连载又来啦!前面的章节不知你还记得吗?还想再回顾一下的朋友可以到文末的推荐阅读里观看哦!

前三章的内容是为方便想在短时间内马上用上 Kotlin 的人,例如作为一个刚入职的新人,公司的代码已经是用 Kotlin 编写了,你应该如何更快的融入与适应?

 

目录

第一部分——快速上手
第一章·启程 
第二章·基本语法
第三章·Kotlin 与 Java 混编 
第二部分——开始学习 Kotlin
第四章·Kotlin 的类特性(上)
第四章·Kotlin 的类特性(下)
第五章·函数与闭包
第六章·集合泛型与操作符

Kotlin 程序是什么样子的?如果浏览过本书,你会看到许多例子。很有可能你觉得 Kotlin 语言有点古怪,充满了var field: String这样的语法。然而读完本章后,你将不再对这些语法感到陌生,甚至很可能喜欢上它们。


2.1 变量


让我们来看一个很简单的程序。

fun main(args: Array<String>) {    
   var quantity = 5
   val price: Double = 20.3
   val name: String = "大米"

   println("单价:$price")
   println("数量:$quantity")
   println("产品:$name 总计:${quantity * price}")
}

上面的代码中,首先创建了一个名为 quantity 的变量用以表示产品的数量,并初始化为 5。


一个值为 20.3 的常量 price,用来表示产品的单价。

一个表示产品名字的字符串常量 name。


通过这段代码我们可以看到,Kotlin 语言声明一个变量使用关键字 var,声明一个常量使用 val,声明时 Kotlin 语言是可以自动推测出字段类型的,例如上面代码中的 var quantity = 5 会被认为是 In t类型,但如果你希望它是一个 Double 类型,则需要显示声明类型,例如 var quantity: Double = 5。


2.2 语句


2.2.1 in关键字的使用


判断一个对象是否在某一个区间内,可以使用in关键字

if (x in 1..y-1) 
 print("OK")

//如果x不存在于array中,则输出Out
if (x !in 0..array.lastIndex)
 print("Out")

//打印1到5
for (x in 1..5)
 print(x)

//遍历集合(类似于Java中的for(String name : names))
for (name in names)
 println(name)

//如果names集合中包含text对象则打印yes
if (text in names)
 print("yes")

2.2.2 when表达式


类似于 Java 中的 switch,但是 Kotlin 更加智能,可以自动判断参数的类型并转换为响应的匹配值。

fun cases(obj: Any) { 
 when (obj) {
   1       -> print("第一项")
   "hello" -> print("这个是字符串hello")
   is Long -> print("这是一个Long类型数据")
   !is String -> print("这不是String类型的数据")
   else    -> print("else类似于Java中的default")
 }
}

2.2.3 智能类型推测


判断一个对象是否为一个类的实例,可以使用 is 关键字与 Java 中的 instanceof 关键字类似,但在 Kotlin 中如果已经确定了一个对象的类型,可以在接下来的代码块中直接作为这个确定类型使用。

fun getStringLength(obj: Any): Int? {
 if (obj is String) {
   // 做过类型判断以后,obj会被系统自动转换为String类型
   return obj.length
 }

 //同时还可以使用!is,来取反
 if (obj !is String){
 }

 // 代码块外部的obj仍然是Any类型的引用
 return null
}

2.2.4 空值检测


Kotlin 是空指针安全的,也就意味着你不会再看到那恼人的空指针异常。
例如这句代码 println(files?.size),只会在 files 不为空时执行。


以及,你可以这样写

//当data不为空的时候,执行语句块
data?.let{
 //...
}

//相反的,以下代码当data为空时才会执行
data?:let{
 //...
}

2.3 函数


2.3.1 函数的声明


函数使用关键字 fun 声明,如下代码创建了一个名为 say() 的函数,它接受一个String 类型的参数,并返回一个 String 类型的值

fun say(str: String): String {
 return str
}

同时,在 Kotlin 中,如果像这种简单的函数,可以简写为

fun say(str: String): String = str

如果是返回Int类型,那么你甚至连返回类型都可以不写

fun getIntValue(value: Int) = value

2.3.2 函数的默认参数


你也可以使用默认参数来实现重载类似的功能

fun say(str: String = "hello"): String = str


这时候你可以调用 say(),来得到默认的字符串 "hello",也可以自己传入参数say("world") 来得到传入参数值。


有时参数非常多的时候,也可以使用多行参数的写法,它们是相同的

fun say(firstName: String = "Tao",
   lastName: String = "Zhang"){
}

2.3.3 变参函数


同 Java 的变长参数一样,Kotlin 也支持变长参数

//在Java中,我们这么表示一个变长函数
public boolean hasEmpty(String... strArray){
 for (String str : strArray){
   if ("".equals(str) || str == null)
     return true;
 }
 return false;
}

//在Kotlin中,使用关键字vararg来表示
fun hasEmpty(vararg strArray: String?): Boolean{
 for (str in strArray){
   if ("".equals(str) || str == null)
     return true  
 }
 return false
}

2.3.4 扩展函数


你可以给父类添加一个方法,这个方法将可以在所有子类中使用
例如,在 Android 开发中,我们常常使用这样的扩展函数:

fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
   Toast.makeText(this, message, duration).show()
}

这样,我们就可以在每一个 Activity 中直接使用 toast() 函数了。


2.3.5 将函数作为参数


Kotlin 中,可以将一个函数作为参数传递给另一个函数

kotlin fun lock<T>(lock: Lock, body: () -> T ) : T { lock.lock() try { return body() } finally { lock.unlock() } } 上面的代码中,我们传入了一个无参的 body() 作为 lock() 的参数。


2.4 小结


最后,我们用一段代码来总结本章内容,你能看懂吗?

fun main(args: Array<String>) {

   val firstName: String = "Tao"
   val lastName: String? = "Zhang"

   println("my name is ${getName(firstName, lastName)}")
}

fun hasEmpty(vararg strArray: String?): Boolean {
   for (str in strArray) {
       str ?: return true
   }
   return false
}

fun getName(firstName: String?, lastName: String? = "unknow"): String {
   if (hasEmpty(firstName, lastName)) {
       lastName?.let { return@getName "${checkName(firstName)} $lastName" }
       firstName?.let { return@getName "$firstName ${checkName(lastName)}" }
   }
   return "$firstName $lastName"
}

fun checkName(name: String?): String = name ?: "unknow"


今天的连载就先到这啦,后续精彩内容请持续关注「沪江技术学院」。

End

推荐阅读

那些年写Kotlin遇到的各种坑,您需要收藏啦

连载 | Kotlin基础语法

连载 | Kotlin简单项目

连载 | Kotlin Primer·第一章·启程