一、前言
<font face= 黑体>在 给 Android 开发者的 Kotlin 教程(二)中我们讲了 Kotlin 的必备基础,分别是 Kotlin 中的<font color= red>基本数据类型、数组</font>以及<font color= red>集合</font>这三大知识点。
<font face= 黑体>这一节我们来讲一下 Kotlin 中的<font color= red>方法</font>和<font color= red> Lambda 表达式</font>这两个知识点。
二、Kotlin 方法
<font face= 黑体>在 Java 中对象是最重要的,而在 Kotlin 中,方法才是最重要的,Kotlin 中方法是可以直接定义在文件里面的,不需要一定定义在类里面。
2.1、方法声明
<font face= 黑体>Kotlin 中一个方法的基本格式如下所示:
<font face= 黑体>具体代码实现
fun plus(a: Int, b: Int): Int {
return a + b
}
2.1.1、类的成员方法
<font face= 黑体>类的成员方法的写法
class Person {
// 成员方法
fun test1() {
println("成员方法")
}
}
<font face= 黑体>成员方法的调用方式
fun main() {
Person().test1()
}
2.1.2、类方法(静态方法)
<font face= 黑体>Kotlin 中并没有 static 关键字,不过我们可以借助companion object(Kotlin 的伴生对象) 来实现类方法的目的。
<font face= 黑体>静态方法的写法
class Person {
companion object {
fun test2() {
println("companion object 实现类方法")
}
}
}
<font face= 黑体>静态方法的调用
Person.test2()
2.1.3、静态方法
<font face= 黑体>在 Kotlin 中如果我们想实现一个工具类 util 的话,可以借助 object 关键字,用 object 关键字修饰的类中的方法都是"静态方法"。
<font face= 黑体>object 修饰的类的写法
object NumUtil {
fun double(num: Int): Int {
return num * 2
}
}
<font face= 黑体>静态方法的调用
println("umUtil.double(2): ${NumUtil.double(2)}")
2.1.4、单表达式方法
当方法返回单个表达式时,可以省略花括号并且在 = 符号之后指定代码体即可。
<font face= 黑体>单表达式方法的写法
fun double(x: Int): Int = x * 2
2.2、方法参数
2.2.1、默认参数
<font face= 黑体>在 Kotlin 中,可以给方法设置一些默认参数,当省略相应的参数时使用默认参数值。与 Java 相比,这可以减少重载数量。
<font face= 黑体>默认参数写法
// off 的默认值就是 0, len 的默认值就是 b.size
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
}
2.2.2、可变数量的参数
<font face= 黑体>在 Java 中利用 ...(比如 String...) 来设置可变类型的参数,在 Kotlin 中是通过 vararg 修饰符标记参数来实现可变参数的。
<font face= 黑体>可变参数写法
// 通过 vararg 修饰
fun append(vararg str: Char): String {
val result = StringBuffer()
for (char in str) {
result.append(char)
}
return result.toString()
}
<font face= 黑体>可变参数方法的调用
println(append('h', 'e', 'l', 'l', 'o'))
2.3、方法作用域
<font face= 黑体>在 Kotlin 中方法可以在文件顶层声明,这意味着你不需要像 Java 那样需要创建一个类来保存一个方法。
<font face= 黑体>此外除了顶层方法,Kotlin 中方法也可以声明在局部作用域、作为成员方法以及扩展方法。
2.3.1、局部方法
<font face= 黑体>局部方法写法
fun rand(): Int {
// 局部方法
fun square(v: Int): Int {
return v * v
}
// 生成 0 到 100 的随机数(包括0、100)
val v1 = (0..100).random()
return square(v1)
}
<font face= 黑体>局部方法的调用
println(rand())
三、Lambda 表达式
<font face= 黑体>Java 是在 Java 8 的时候开始支持Lambda表达式的,目前 Lambda 语法在 Java 中已经被广泛的运用,Lambda 表达式可以理解为是一种语法糖,值得庆幸的是,Kotlin 一经开源就已经支持这种语法。
<font face= 黑体>Lambda 作为方法式编程的基础,其语法也是相当简单的。这里先通过一段简单的代码演示没来了解一下 Lambda 表达式的简洁之处。
<font face= 黑体>点击事件,未用 Lambda 表达式
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "Lambda 简洁之道", Toast.LENGTH_LONG).show();
}
});
<font face= 黑体>点击事件,使用 Lambda 表达式
view.setOnClickListener { v -> Toast.makeText(context, "Lambda简洁之道", Toast.LENGTH_LONG).show() }
3.1、Lambda 表达式语法
<font face= 黑体>无参数情况
val/var 变量名 = { 操作的代码 }
fun test() {
println("无参数")
}
// 将上述代码改造成使用 Lambda 表达式代码
val test1 = { println("无参数") }
<font face= 黑体>有参数情况
val/var 变量名 : (参数的类型,参数类型,...) -> 返回值类型 = {参数1,参数2,... -> 操作参数的代码 }
// 此种写法:即表达式的返回值类型会根据操作的代码自推导出来。
val/var 变量名 = { 参数1 : 类型,参数2 : 类型, ... -> 操作参数的代码 }
fun test2(a: Int, b: Int): Int {
return a + b
}
// 将上述代码改造成使用 Lambda 表达式代码
val test3: (Int, Int) -> Int = { a, b -> a + b }
// Lambda 表达式代码简化
val test4 = { a: Int, b: Int -> a + b }
3.2、认识Kotlin 中的 it
<font face= 黑体>it 并不是 Kotlin 中的一个关键字,it是在当一个高阶方法中 Lambda 表达式的参数只有一个的时候可以使用 it 来使用此参数,it 可表示为单个参数的隐式名称,是 Kotlin 语言约定的。
<font face= 黑体>单个参数的隐式名称
// 过滤掉数组中小于 5 的元素,这里的 it 就表示每一个元素
fun test5() {
val arr = arrayOf(1, 2, 3, 4, 5)
println("test5${arr.filter { it < 5 }}")
}
3.2、在 Lambda 表达式中使用_
<font face= 黑体>在使用 Lambda 表达式的时候,可以用下划线(_)表示未使用的参数,表示不处理这个参数。
<font face= 黑体>当遍历 Map 集合的时候,用处非常明显
fun test6() {
val map = mapOf("key1" to "value1", "key2" to "value2", "key3" to "value3")
map.forEach { (key, value) ->
println("$key \t $value")
}
// 不需要key的时候
map.forEach { (_, value) ->
println(value)
}
}
四、完整代码
fun main() {
println("functionLearn: ${functionLearn(101)}")
Person().test1()
Person.test2()
println("umUtil.double(2): ${NumUtil.double(2)}")
println("double(2): ${double(2)}")
println(append('a', 'b', 'c'))
println(magic())
// lambda
test1()
println(test3(1, 3))
test5()
test6()
}
fun plus(a: Int, b: Int): Int {
return a + b
}
fun functionLearn(days: Int): Boolean {
return days > 100
}
class Person {
/**
* 成员方法
*/
fun test1() {
println("成员方法")
}
companion object {
fun test2() {
println("companion object 实现类方法")
}
}
}
/**
* 整个静态类
*/
object NumUtil {
fun double(num: Int): Int {
return num * 2
}
}
/**
* 单表达式方法,当方法当个表达式时,可以省略花括号并且在 = 符号之后指定代码体即可
*/
fun double(x: Int): Int = x * 2
/**
* 默认值,方法参数可以由默认值,当省略相应的参数时使用默认值。与Java相比,这可以减少重载数量
*/
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
}
/**
* 可变数量参数
*/
fun append(vararg str: Char): String {
val result = StringBuffer()
for (char in str) {
result.append(char)
}
return result.toString()
}
/**
* 局部方法
*/
fun magic(): Int {
fun foo(v: Int): Int {
return v * v
}
val v1 = (0..100).random()
return foo(v1)
}
/**
* 无参数情况
*/
fun test() {
println("无参数")
}
val test1 = { println("无参数") }// lambda代码
/**
* 有参数
*/
fun test2(a: Int, b: Int): Int {
return a + b
}
val test3: (Int, Int) -> Int = { a, b -> a + b }// lambda代码
val test4 = { a: Int, b: Int -> a + b }// lambda代码简化
fun test5() {
val arr = arrayOf(1, 2, 3, 4, 5)
println("test5${arr.filter { it < 5 }}")
}
fun test6() {
val map = mapOf("key1" to "value1", "key2" to "value2", "key3" to "value3")
map.forEach { (key, value) ->
println("$key \t $value")
}
// 不需要key的时候
map.forEach { (_, value) ->
println(value)
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。