kotlin 读书笔记
《Kotlin 编程权威指南》 读书笔记
- 1 匿名函数
- 2 null安全的操作符
- 3 标准库函数
- 4 构造函数
- 5 Object 关键字
1 匿名函数
- 函数的定义 就是 把表达式或语句 放到一对 花括号里
{表达式 或 语句}
- 函数类型
kotlin 中 参数 或 返回值 都是类型。 函数作为 ‘一等公民’ 也是一种类型。 使用 (参数)-> 返回类型 表示。
fun greetingFunction() : Strng //返回一个,fun greetingFunction() : () ->Unit // 返回 一个 函数, 该函数 没有参数, 返回值 为 Unitfun greetingFunction() : (Int) ->String// 返回 一个 函数, 该函数接收1个Int参数, 返回值String 的 函数。
Lambda 表达式
在Kotlin中, 我们把 匿名函数的定义 称为 Lambda表达式 。
lambda 函数体里 不能有 return 关键字
Lamdda表达式 默认以函数体 最后一行 代码的值,作为 返回值。it 关键字
当 lambda 表达式 只定义了 一个参数时,可以用 it 来表示参数名。
fun IntRange.pickNum(function: (Int) -> Boolean): List<Int> {val resultList = mutableListOf<Int>()for (i in this) {if (function(i)) resultList.add(i)}return resultList
}
println(list.pickNum{ it % 10 == 0 })
- 调用lambda 时 简略写法
如果函数只有一个参数,且参数为函数类型,调用时可以省略小括号
fun IntRange.pickNum(function: (Int) -> Boolean): List<Int> {val resultList = mutableListOf<Int>()for (i in this) {if (function(i)) resultList.add(i)}return resultList
}println(list.pickNum({ x: Int -> x % 10 == 0 }))println(list.pickNum { x: Int -> x % 10 == 0 })
如果有多个参数,并且最后一个参数是函数类型,调用时可以将函数参数移到括号外
fun IntRange.pickNum(need :Int ,find : Int , function: (Int) -> Boolean): List<Int> {val resultList = mutableListOf<Int>()for (i in this) {if (function(i)) resultList.add(i)}return resultList
}println(list.pickNum(10,100,{ x: Int -> x % 10 == 0 }))println(list.pickNum(10,100) { x: Int -> x % 10 == 0 })
- lambda 是闭包的
在kotlin中,匿名函数能 修改 和引用,定义在自己作用域之外的变量。
fun configureFun(): (String) -> String {val value = "hospitals"var number = 8return { name: String ->val year = 2019number++println("this is result $value number = $number")"welcome to here ,$name ! (copyright $year)"}
}fun main() {val greetingFun = configureFun()println(greetingFun("老王"))println(greetingFun("老李"))println(greetingFun("老张"))
}
打印结果
this is result hospitals number = 9
welcome to here ,老王 ! (copyright 2019)
this is result hospitals number = 10
welcome to here ,老李 ! (copyright 2019)
this is result hospitals number = 11
welcome to here ,老张 ! (copyright 2019)
从结果中,可以发现。外部的变量 value number ,可以在lambda函数里直接调用 和修改。
2 null安全的操作符
- 定义 一个 返回值可以为空的方法
fun readLine() :String ?
String 是 String? 的子类
安全调用操作符 ?. 使用let 的 安全调用
fun readLine(): String? {val number = listOf(1, 2, 3).shuffled().first()if (number > 2) {return "$number"}return null}val beverage = readLine()?.let { if(it =="4"){"${it.toInt() +3 }"}else{"3"}}
非空断言操作符 !!.
空合并操作符 ?:
当 readLine() 返回null时,beverage2 = “123”
val beverage2 = readLine() ?: "123"
3 标准库函数
- apply
源码:
public inline fun <T> T.apply(block: T.() -> Unit): T {contract {callsInPlace(block, InvocationKind.EXACTLY_ONCE)}block()return this
}
参数是 this ,一般使用与 配置某个对象, 返回为 调用的对象本身。
val menuFile = File("xxxx").apply { setReadable(false)setWritable(true)setExecutable(false)}
- let
源码:
public inline fun <T, R> T.let(block: (T) -> R): R {contract {callsInPlace(block, InvocationKind.EXACTLY_ONCE)}return block(this)
}
参数时 it ,返回 lambda表达的值,做空值处理。
fun formatGreeting(vipGuest: String?): String {return vipGuest?.let { "welcome $it. go straight back" } ?: "welcome to the tavern. you will be seated shortly"
}
- run
源码:
public inline fun <T, R> T.run(block: T.() -> R): R {contract {callsInPlace(block, InvocationKind.EXACTLY_ONCE)}return block()
}
和 apply 类似, 参数为this ,但 返回 lambda表达的值
run 常用语 函数的链式调用,能让代码逻辑更清晰
fun nameIsLong(name:String) = name.length >=20fun playerCreatMessage( nameTooLong:Boolean) :String{return if(nameTooLong){"Name is too long,Please choose another name"}else{"Welcome to Adventurer"}}//原代码println(playerCreatMessage(nameIsLong("Polarise,Supreme Master of Netmask")))//run 优化后"Polarise,Supreme Master of Netmask".run(::nameIsLong).run(::playerCreatMessage).run(::println)
with
with 是 run 的变体,功能一样。 不推荐使用, 一般用run替代。also
源码:
public inline fun <T> T.also(block: (T) -> Unit): T {contract {callsInPlace(block, InvocationKind.EXACTLY_ONCE)}block(this)return this
}
和let 类似,参数 it , 返回对象本身。
val numbers = mutableListOf("one", "two", "three")
numbers.also { println("The list elements before adding new one: $it") }.add("four")
- takeIf
源码:
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {contract {callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)}return if (predicate(this)) this else null
}
功能类型 if else 。 参数 it , 返回 true 或者 null
val str = "Hello"
val caps = str.takeIf { it.isNotEmpty() }?.toUpperCase()fun displaySubstringPosition(input: String, sub: String) {input.indexOf(sub).takeIf { it >= 0 }?.let {println("The substring $sub is found in $input.")println("Its start position is $it.")}
}
4 构造函数
- 主构造函数
class Cat( master: String, var name:String, val age :Int, color: Color = Color.BLACK){}
需要注意的是主构造函数不包含任何代码,初始化程序块用于初始化代码
- 次级构造函数
class Cat( master: String, var name:String, val age :Int, color: Color = Color.BLACK){constructor(master: String): this(master,age = 3, name ="喵喵")}
我们可以在同一类中使用主构造函数和次级构造函数。通过在一个类中使用主和次级构造函数,次级构造函数需要授权给主构造函数,也就是次级构造函数会直接或者间接调用主构造函数。使用this()关键字对同一个类中的另一个构造函数进行授权。
构造函数 参数 可以是 var val ,也可以给初始值。
- 初始化顺序
1 主构造函数里声明的属性
2 类级别的属性赋值
3 init 初始代码块的属性赋值 和 函数调用
4 次级构造函数里的 属性赋值 和 函数调用
特殊说明: 2 3 条,init 初始化代码块 和 类级别的属性赋值, 顺序 取决于 定义的先后顺序。
5 Object 关键字
object 的使用 有3种方式: 对象声明 对象表达式 伴生对象
- 对象声明
单例模式
object Game{const val TAG = "lsh"init {println("这是 一个 单例")}fun getSomething() : String {return "给你点 惊喜!"}
}fun main(args: Array<String>) {Game.getSomething()var tag = Game.TAG
}
- 对象表达式
创建继承某个(或某些)类型的匿名类的对象,这些类型可以是接口 抽象类 普通类
button.setOnClickListener(object: View.OnClickListener {override fun onClick(v: View?) {Log.d(MainActivity::class.java.simpleName, "click button")}})open class Man(_name: String) {val name = _name
}interface Flyable {fun fly()
}interface SuperHearing {fun hearSubtleNoises()
}fun main(args: Array<String>) {val superMan = object : Man("Clark"),Flyable,SuperHearing{override fun fly() {println("i can fly")}override fun hearSubtleNoises() {println(" hearSubtleNoises ")}}
}
对象表达式后面可以不跟任何类或者接口,这时它仅仅表示一个对象,封装一些数据和方法
val litCat = object {val name = "喵喵"fun eat(){println("我 吃 鱼")}}litCat.eat()litCat.name
- 伴生对象
关键字 companion object , 可以理解 为 java 里的 静态变量 静态方法。
class MyActivity : AppCompatActivity() {companion object {const val TAG = "MyActivity"@JvmStatic // 如果在 Java 代码中调用此方法,必须加上这个注解,才能编译出静态方法fun start(context: Context) {val starter = Intent(context, MyActivity::class.java)context.startActivity(starter)}}
}
kotlin 读书笔记相关推荐
- Kotlin读书笔记之内联函数、扩展函数、匿名函数、lambda
本文主要涉及内联函数.扩展函数.lambada以及匿名函数等.作为读书笔记对于细节深入没有过多的扩展,后续将对于各个知识点作进一步的研度.本文的内容主要是参考官方教程以及博客内容,作为读书笔记以及后续 ...
- Kotlin读书笔记之函数式kotlin
一. 使用lambda进行函数式编程 函数式代码是声明式的 - 你关注于做什么,并将如何做的细节分配给底层函数库.现在的Java这种命令式编程在去过很长时间都是主流,Java处理命令式风格还有面向对象 ...
- Kotlin读书笔记之优雅且高效的Kotlin
一. Kotlin的流畅性 1.1. 重载运算符 说到运算符重载,是不是想起来大学被C++折磨的日子.传统上,我们对数值类型来创建表达式,例如:2 + 3 或 4.2 * 7.1.运算符重载是一种特性 ...
- kotlin读书笔记之类与对象
1. 类与继承 1.1 类的用法 与java一样使用class声明类,后面可以跟着大括号: class Invoice { /*--*/ } class Empty 1.2 构造函数 kotlin可以 ...
- kotlin读书笔记之基础语法
1.初识Kotlin 1.1 变量 变量的定义写法上和java差别挺大的.变量分为可读以及可读可写,而且kotlin会自动推测出变量的类型,可推测的情况下. val a: Int = 1 // 立即赋 ...
- kotlin读书笔记之函数基本知识以及泛型
1.函数内容 1.1 函数的声明与用法 kotlin的函数使用fun关键字声明,如下所示: fun double(x: Int): Int {return 2 * x } double(2).tost ...
- 【读书笔记】知易行难,多实践
前言: 其实,我不喜欢看书,只是喜欢找答案,想通过专业的解答来解决我生活的困惑.所以,我听了很多书,也看了很多书,但看完书,没有很多的实践,导致我并不很深入在很多时候. 分享读书笔记: <高效1 ...
- 读书笔记:编写高质量代码--web前端开发修炼之道(二:5章)
读书笔记:编写高质量代码--web前端开发修炼之道 这本书看得断断续续,不连贯,笔记也是有些马虎了,想了解这本书内容的童鞋可以借鉴我的这篇笔记,希望对大家有帮助. 笔记有点长,所以分为一,二两个部分: ...
- 《编程匠艺》读书笔记
<编程匠艺>读书笔记之一 <编程匠艺>读书笔记之二 <编程匠艺>读书笔记之三 <编程匠艺>读书笔记之四 <编程匠艺>读书笔记之五 <编 ...
最新文章
- 复杂个人信息输出程序python_Python高级技巧:用一行代码减少一半内存占用
- 后盾网lavarel视频项目---自定义验证和自定义验证规则
- 基于 Nginx 的 HTTPS 性能优化实践
- noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25
- 招兵买马,亚马逊再次补强人工智能
- 接口测试——Fiddler使用要点——笔记整理
- Windows Server 2016 搭建 FTP服务
- int main(int argc,char *argv[])该函数中int argc和argv[]两个参数的理解你懂多少?
- python客户端软件开发_用 Python 实现一个简易版 HTTP 客户端
- 视频教程-华为HCNA网络工程师【从入门到精通】自学视频[肖哥]-华为认证
- 计算机wmi配置错误,系统没有WMI服务、WMI错误修复办法
- WEEK 7作业 A-TT的魔法猫 B-TT的旅行日记 C-TT的美梦
- 《Python 深度学习》刷书笔记 Chapter 8 Part-2 用Keras 实现 DeepDream
- LODOP设计打印模板
- windows命令——taskmgr 1
- 信息系统项目管理师必背核心考点(七十二)V模型
- 2021年机修钳工(中级)考试题库及机修钳工(中级)试题解析
- decimal 和 numeric
- #define宏的妙用!实现你以为的函数offsetof等
- NPN和PNP开关电路使用