kotlin 入门中文教程(1),安卓常见面试题知乎

println("(intValue + 100) value is ${intValue + 100}") //(intValue + 100) value is 200

如果你需要在原始字符串中表示字面值($)字符(它不支持反斜杠转义),可以用下列语法:

val price = “KaTeX parse error: Expected '}', got 'EOF' at end of input: {'’}100.99”
println(price) //$100.99

3.3、数组

kotlin 中的数组是带有类型参数的类,其元素类型被指定为相应的类型参数,使用 Array 类来表示, Array 类定义了 get 与 set 函数(按照运算符重载约定这会转变为 [ ] )以及 size 属性等

创建数组的方法有以下几种:

  1. 用 arrayOf 函数创建一个数组,包含的元素是指定为该函数的实参
  2. 用 arrayOfNulls 创建一个给定大小的数组,包含的元素均为 null,只能用来创建包含元素类型可空的数组
  3. 调用 Array 类的构造方法,传递数组的大小和一个 lambda 表达式,调用 lambda 表达式来创建每一个数组元素

//包含给定元素的字符串数组
val array1 = arrayOf(“leavesC”, “叶”, “https://github.com/leavesC”)

array1[0] = “leavesC”
println(array1[1])
println(array1.size)

//初始元素均为 null ,大小为 10 的字符数组
val array2 = arrayOfNulls(10)

//创建从 “a” 到 “z” 的字符串数组
val array3 = Array(26) { i -> (‘a’ + i).toString() }

需要注意的是,数组类型的类型参数始终会变成对象类型,因此声明 Array< Int > 将是一个包含装箱类型(java.lang.Integer)的数组。如果想要创建没有装箱的基本数据类型的数组,必须使用一个基本数据类型数组的特殊类

为了表示基本数据类型的数组,kotlin 为每一种基本数据类型都提供了若干相应的类并做了特殊的优化。例如,有 IntArray、ByteArray、BooleanArray 等类型,这些类型都会被编译成普通的 Java 基本数据类型数组,比如 int[]、byte[]、boolean!
[]
等,这些数组中的值存储时没有进行装箱,而是使用了可能的最高效的方式。需要注意,IntArray 等并不是 Array 的子类

要创建一个基本数据类型的数组,有以下几种方式:

  1. 向对应类型的类(如 IntArray)的构造函数传递数组大小,这将返回一个使用对应基本数据类型默认值初始化好的数组
  2. 向对应类型的类(如 IntArray)的构造函数传递数组大小以及用来初始化每个元素的 lambda
  3. 向工厂函数(如 charArrayOf)传递变长参数的值,从而得到指定元素值的数组

//指定数组大小,包含的元素将是对应基本数据类型的默认值(int 的默认值是 0)
val intArray = IntArray(5)
//指定数组大小以及用于初始化每个元素的 lambda
val doubleArray = DoubleArray(5) { Random().nextDouble() }
//接收变长参数的值来创建存储这些值的数组
val charArray = charArrayOf(‘H’, ‘e’, ‘l’, ‘l’, ‘o’)

3.4、Any 和 Any?

Any 类型是 kotlin 所有非空类型的超类型,包括像 Int 这样的基本数据类型

如果把基本数据类型的值赋给 Any 类型的变量,则会自动装箱

val any: Any = 100
println(any.javaClass) //class java.lang.Integer

如果想要使变量可以存储包括 null 在内的所有可能的值,则需要使用 Any?

val any: Any? = null

3.5、Unit

kotlin 中的 Unit 类型类似于 Java 中的 void,可以用于函数没有返回值时的情况

fun check(): Unit {

}

//如果返回值为 Unit,则可以省略该声明
fun check() {

}

Unit 是一个完备的类型,可以作为类型参数,但 void 不行

interface Test {
fun test(): T
}

class NoResultClass : Test {

//返回 Unit,但可以省略类型说明,函数也不需要显式地 return
override fun test() {

}

}

3.6、Nothing

Nothing 类型没有任何值,只有被当做函数返回值使用,或者被当做泛型函数返回值的类型参数使用时才会有意义,可以用 Nothing 来表示一个函数不会被正常终止,从而帮助编译器对代码进行诊断

编译器知道返回值为 Nothing 类型的函数从不正常终止,所以编译器会把 name1 的类型推断为非空,因为 name1 在为 null 时的分支处理会始终抛出异常

data class User(val name: String?)

fun fail(message: String): Nothing {
throw IllegalStateException(message)
}

fun main() {
val user = User(“leavesC”)
val name = user.name ?: fail(“no name”)
println(name) //leavesC

val user1 = User(null)
val name1 = user1.name ?: fail(“no name”)
println(name1.length) //IllegalStateException
}

四、函数

kotlin 中的函数以关键字 fun 作为开头,函数名称紧随其后,再之后是用括号包裹起来的参数列表,如果函数有返回值,则再加上返回值类型,用一个冒号与参数列表隔开

//fun 用于表示声明一个函数,getNameLastChar 是函数名
//空括号表示该函数无传入参数,Char 表示函数的返回值类型是字符
fun getNameLastChar(): Char {
return name.get(name.length - 1)
}

//带有两个不同类型的参数,一个是 String 类型,一个是 Int 类型
//返回值为 Int 类型
fun test1(str: String, int: Int): Int {
return str.length + int
}

此外,表达式函数体的返回值类型可以省略,返回值类型可以自动推断,这种用单行表达式与等号定义的函数叫做表达式函数体。但对于一般情况下的有返回值的代码块函数体必须显式地写出返回类型和 return 语句

//getNameLastChar 函数的返回值类型以及 return 关键字是可以省略的
//返回值类型可以由编译器根据上下文进行推导
//因此,函数可以简写为以下形式
fun getNameLastChar() = name.get(name.length - 1)

如果函数没有有意义的返回值,则可以声明为 Unit ,也可以省略 Unit

以下三种写法都是等价的

fun test(str: String, int: Int): Unit {
println(str.length + int)
}

fun test(str: String, int: Int) {
println(str.length + int)
}

fun test(str: String, int: Int) = println(str.length + int)

4.1、命名参数

为了增强代码的可读性,kotlin 允许我们使用命名参数,即在调用某函数的时候,可以将函数参数名一起标明,从而明确地表达该参数的含义与作用,但是在指定了一个参数的名称后,之后的所有参数都需要标明名称

fun main() {
//错误,在指定了一个参数的名称后,之后的所有参数都需要标明名称
//compute(index = 110, “leavesC”)
compute(index = 120, value = “leavesC”)
compute(130, value = “leavesC”)
}

fun compute(index: Int, value: String) {

}

4.2、默认参数值

可以在声明函数的时候指定参数的默认值,从而避免创建重载的函数

fun main() {
compute(24)
compute(24, “leavesC”)
}

fun compute(age: Int, name: String = “leavesC”) {

}

对于以上这个例子,如果按照常规的调用语法时,必须按照函数声明定义的参数顺序来给定参数,可以省略的只有排在末尾的参数

fun main() {
//错误,不能省略参数 name
// compute(24)
// compute(24,100)
//可以省略参数 value
compute(“leavesC”, 24)
}

fun compute(name: String = “leavesC”, age: Int, value: Int = 100) {}

如果使用命名参数,可以省略任何有默认值的参数,而且也可以按照任意顺序传入需要的参数

fun main() {
compute(age = 24)
compute(age = 24, name = “leavesC”)
compute(age = 24, value = 90, name = “leavesC”)
compute(value = 90, age = 24, name = “leavesC”)
}

fun compute(name: String = “leavesC”, age: Int, value: Int = 100) {

}

4.3、可变参数

可变参数可以让我们把任意个数的参数打包到数组中传给函数,kotlin 的语法相比 Java 有所不同,改为通过使用 varage 关键字声明可变参数

例如,以下的几种函数调用方式都是正确的

fun main() {
compute()
compute(“leavesC”)
compute(“leavesC”, “叶应是叶”)
compute(“leavesC”, “叶应是叶”, “叶”)
}

fun compute(vararg name: String) {
name.forEach { println(it) }
}

在 Java 中,可以直接将数组传递给可变参数,而 kotlin 要求显式地解包数组,以便每个数组元素在函数中能够作为单独的参数来调用,这个功能被称为展开运算符,使用方式就是在数组参数前加一个 *

fun main() {
val names = arrayOf(“leavesC”, “叶应是叶”, “叶”)
compute(* names)
}

fun compute(vararg name: String) {
name.forEach { println(it) }
}

4.4、局部函数

kotlin 支持在函数中嵌套函数,被嵌套的函数称为局部函数

fun main() {
compute(“leavesC”, “country”)
}

fun compute(name: String, country: String) {
fun check(string: String) {
if (string.isEmpty()) {
throw IllegalArgumentException(“参数错误”)
}
}
check(name)
check(country)
}

五、表达式和条件循环

5.1、语句和表达式

这里需要先区分“语句”和“表达式”这两个概念。语句是可以单独执行,能够产生实际效果的代码,表现为赋值逻辑、打印操作、流程控制等形式,Java 中的流程控制(if,while,for)等都是语句。表达式可以是一个值、变量、常量、操作符、或它们之间的组合,表达式可以看做是包含返回值的语句

例如,以下的赋值操作、流程控制、打印输出都是语句,其是作为一个整体存在的,且不包含返回值

val a = 10
for (i in 0…a step 2) {
println(i)
}

再看几个表达式的例子

1 //字面表达式,返回 1
++1 //自增,返回 2
//与 Java 不同,kotlin 中的 if 是作为表达式存在的,其可以拥有返回值
fun getLength(str: String?): Int {
return if (str.isNullOrBlank()) 0 else str.length
}

5.2、If 表达式

if 的分支可以是代码块,最后的表达式作为该块的返回值

val maxValue = if (20 > 10) {
println(“maxValue is 20”)
20
} else {
println(“maxValue is 10”)
10
}
println(maxValue) //20

以下代码可以显示地看出 if 的返回值,完全可以用来替代 Java 中的三元运算符,因此 kotlin 并没有三元运算符

val list = listOf(1, 4, 10, 4, 10, 30)
val value = if (list.size > 0) list.size else null
println(value) //6

如果 if 表达式分支是用于执行某个命令,那么此时的返回值类型就是 Unit ,此时的 if 语句就看起来和 Java 的一样了

val value1 = if (list.size > 0) println(“1”) else println(“2”)
println(value1.javaClass) //class kotlin.Unit

如果将 if 作为表达式而不是语句(例如:返回它的值或者把它赋给变量),该表达式需要有 else 分支

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值