Skip to content

Commit 45d0900

Browse files
committed
update kolin part
1 parent 2fbd8d6 commit 45d0900

3 files changed

Lines changed: 61 additions & 253 deletions

File tree

‎KotlinCourse/Kotlin学习教程(七).md‎

Lines changed: 12 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,21 @@ Runnable runnable2=()->{
3636

3737
`Lambda`能让代码更简洁,而主打简洁的`Kotlin`怎么可能不支持呢? 当然会支持。
3838

39-
下面来看看一个简短的概述:
39+
下面来看看一个简短的概述:
4040

41-
lambda 表达式总是被大括号括着,
42-
其参数(如果有的话)在 -> 之前声明(参数类型可以省略),
43-
函数体(如果存在的话)在 -> 后面。
44-
45-
46-
Lambda表达式是定义匿名函数的简单方法。由于Lambda表达式避免在抽象类或接口中编写明确的函数声明,进而也避免了类的实现部分,所以它是非常有用的。在Kotlin语言中,可以将一函数作为另一函数的参数。例如,可以将需要回调(callback)的函数简单化为:
47-
48-
49-
Lambda表达式由箭头左侧函数的参数(在圆括号里的内容)定义的,将值返回到箭头右侧。在这个例子中,得到的View返回给Unit(无参数)。按此思路,可以上述代码略做简化:
50-
view.setOnClickListener({ view -> toast("Click")})
51-
在定义函数时,必须在箭头的左侧用方括号,并指定参数值,而函数的执行代码在箭头右侧。如果左侧不使用参数,甚至可以省去左侧部分:
52-
view.setOnClickListener({ toast("Click") })
53-
如果函数的最后一个参数是一个函数的话,可以将作为参数的函数移到圆括号外面:
54-
view.setOnClickListener() { toast("Click") }
41+
- `lambda`表达式总是被大括号括着
42+
- 其参数(如果有的话)在` -> `之前声明(参数类型可以省略),
43+
- 函数体(如果存在的话)在` -> `后面。
5544

45+
`Lambda`表达式是定义匿名函数的简单方法。由于`Lambda`表达式避免在抽象类或接口中编写明确的函数声明,进而也避免了类的实现部分,所以它是非常有用的。
46+
在`Kotlin`语言中,可以将一函数作为另一函数的参数。
5647

48+
`Lambda`表达式由箭头左侧函数的参数(在圆括号里的内容)定义的,将值返回到箭头右侧。
49+
`view.setOnClickListener({ view -> toast("Click")})`
50+
在定义函数时,必须在箭头的左侧用方括号,并指定参数值,而函数的执行代码在箭头右侧。如果左侧不使用参数,甚至可以省去左侧部分:
51+
`view.setOnClickListener({ toast("Click") })`
52+
如果函数的最后一个参数是一个函数的话,可以将作为参数的函数移到圆括号外面:
53+
`view.setOnClickListener() { toast("Click") }`
5754

5855

5956
先看一个例子:
@@ -84,175 +81,6 @@ val sum: (Int, Int) -> Int = { x, y -> x + y }
8481
而且此`Lambda`表达式之前有一个匿名的函数声明(在此例中两个`Int`型的输入,一个`Int`型的返回值),这个声明是可以不使用的。
8582
则此`Lambda`表达式变成`val sum = { x: Int, y: Int -> x + y }`,此时`Lambda`表达式会根据主体中的最后一个(或可能是单个)表达式会视为返回值。
8683
当然,在某些特定情况下,`x`、`y`的类型了是可以推断的,所以`val sum = { x, y -> x + y }`。
87-
88-
89-
90-
91-
一、Lambda的定义
92-
93-
看上面的说法有点抽象,有点不明所以,我们先来看一个栗子
94-
95-
class Num {
96-
fun logic(a: Int, b: Int, calc: (Int, Int) -> Int){
97-
println("calc : ${calc(a,b)}")
98-
}
99-
}
100-
101-
fun main(args : Array<String>){
102-
val num = Num()
103-
num.logic(1, 2, {x,y -> x+y})
104-
}
105-
106-
// 输出
107-
calc : 3
108-
这个栗子和上一篇文章很像,只是在调用的时候改成了Lambda方式:num.logic(1, 2, {x,y -> x+y}),其中{x,y -> x+y}就是我们今天要讲的Lambda表达式,它的完整格式应该是这样
109-
110-
{ x: Int, y: Int -> x + y }
111-
写成java代码是这个样子:
112-
113-
public int sum(int x, int y){
114-
return x+y;
115-
}
116-
可以很明显看出有几个规则:
117-
118-
参数写在->左边,格式与普通函数的参数格式一样,多个参数用逗号,分割
119-
参数的类型可选,可忽略,编辑器会根据上下文推断(这就和普通函数不一样了吧,有种“我知道你懂得,所以就不写了”的感觉有木有,知己的感觉啊……)
120-
函数体跟在->右边
121-
Lambda表达式总是被大括号{}包围着
122-
二、Lambda中的一些约定
123-
124-
如果 Kotlin 可以自己计算出签名,它允许我们不声明唯一的参数,并且将隐含地为我们声明其名称为 it。其实通常情况下它都可以自己计算出签名,也就是说,如果函数字面值只有一个参数, 那么它的声明可以省略(连同 ->),其名称是 it
125-
126-
fun oneParams(one : (Int) -> Int){
127-
println("oneParams : ${one(5)}")
128-
}
129-
130-
fun main(args : Array<String>){
131-
val num = Num()
132-
num.oneParams({it * 2})
133-
}
134-
135-
// 输出
136-
oneParams : 10
137-
说到省略,其实还有一种情况可以省略->,大家应该也能想到,就是无参函数。
138-
139-
fun empty(emptyM : () -> Unit){
140-
emptyM()
141-
}
142-
143-
fun main(args : Array<String>){
144-
val num = Num()
145-
num.empty({println("empty method")})
146-
}
147-
148-
// 输出
149-
empty method
150-
如果Lambda中的某个参数没有用到,可以用下划线_代替,也就是说,省了好多请名字的脑细胞有木有!这个特性从1.1开始可以使用,现在你看到的时候应该已经不止1.1了吧,所以这个限制看看就好~
151-
152-
fun unusedParams(unused : (Int,Int) -> Int){
153-
println("unusedParams : ${unused(5,10)}")
154-
}
155-
156-
fun main(args : Array<String>){
157-
val num = Num()
158-
num.unusedParams { _, used -> used * 2 }
159-
}
160-
161-
// 输出
162-
unusedParams : 20
163-
如果函数的最后一个参数是一个函数,那么我们在用Lambda表达最后一个函数参数的时候,可以把它放在括号()外面,所以下面的写法是等价的。
164-
165-
class Num {
166-
fun logic(a: Int, b: Int, calc: (Int, Int) -> Int){
167-
println("calc : ${calc(a,b)}")
168-
}
169-
fun sum(a: Int, b: Int) = a + b
170-
}
171-
172-
fun main(args : Array<String>){
173-
val num = Num()
174-
// 写法1
175-
num.logic(1, 2, {x : Int,y : Int -> x+y})
176-
// 写法2
177-
num.logic(1, 2){x : Int,y : Int -> x+y}
178-
// 写法3
179-
num.logic(1, 2){x,y -> x+y}
180-
}
181-
那么这么写有什么好处呢?难道只是位置变了一下?当然不是,不要忘记,Lambda的->后面是方法体,也就是很多时候不是想栗子中这样只有一行,如果有多行的话,体会一下他们的区别:
182-
183-
num.logic(1, 2, {x,y ->
184-
println("extra line")
185-
x+y
186-
})
187-
188-
num.logic(1, 2){x,y ->
189-
println("extra line")
190-
x+y
191-
}
192-
是不是感觉下面的写法要优雅很多,也明确很多?
193-
194-
其实在上面一点应该已经能看出,如果有需要的话,Lambda会隐式的返回最后一个表达式的值,就像上面的最后一行x+y。当然,我们也可以显示的表达返回值,下面的写法还是一样的:
195-
196-
// 写法1
197-
num.unusedParams { _, used ->
198-
println("print first")
199-
return@unusedParams used * 2
200-
}
201-
202-
// 写法2
203-
num.unusedParams { _, used ->
204-
println("print first")
205-
used * 2
206-
}
207-
三、匿名函数
208-
209-
看了这么多,我们发现一个问题,Lambda的返回类型全是自动推断的,虽然很人性化,但是有时候我们就是想自己指定类型怎么办?当然是有办法的,那就是匿名函数。
210-
211-
fun(x:Int, y:Int):Int{return x+y}
212-
匿名函数看起来非常像一个常规函数声明,除了其名称省略了。其函数体可以是表达式(如上所示)或代码块。由于这已经不算正经的Lambda,所以它不需要被大括号{}包裹,也不能像Lambda一样写在括号()外,而调用也是直接调用。
213-
214-
num.logic(1, 2, fun(x:Int, y:Int):Int{return x+y})
215-
四、闭包
216-
217-
Lambda 表达式或者匿名函数(以及局部函数和对象表达式) 可以访问其 闭包 ,即在外部作用域中声明的变量。 与 Java 不同的是可以修改闭包中捕获的变量:
218-
219-
var sum = 0
220-
ints.filter { it > 0 }.forEach {
221-
sum += it
222-
}
223-
print(sum)
224-
225-
226-
227-
228-
229-
230-
231-
232-
233-
234-
235-
236-
237-
238-
239-
240-
241-
242-
243-
244-
245-
246-
247-
248-
249-
250-
251-
252-
253-
254-
255-
25684

25785

25886

‎KotlinCourse/Kotlin学习教程(九).md‎

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,37 @@ Kotlin学习教程(九)
22
===
33

44

5-
### Kotlin用到的关键字
6-
7-
- var:定义变量
8-
- val:定义常量
9-
- fun:定义方法
10-
- Unit:默认方法返回值,类似于Java中的void,可以理解成返回没什么用的值
11-
- vararg:可变参数
12-
- $:字符串模板(取值)
13-
- 位运算符:or(按位或),and(按位与),shl(有符号左移),shr(有符号右移),
14-
- ushr(无符号右移),xor(按位异或),inv(按位取反)
15-
- in:在某个范围中 检查值是否在或不在(in/!in)范围内或集合中
16-
- downTo:递减,循环时可用,每次减1
17-
- step:步长,循环时可用,设置每次循环的增加或减少的量
18-
- when:Kotlin中增强版的switch,可以匹配值,范围,类型与参数
19-
- is:判断类型用,类似于Java中的instanceof()is运算符检查表达式是否是类型的实例。 如果一个不可变的局部变量或属性是指定类型,则不需要显式转换:
20-
21-
- private //仅在同一个文件中可见
22-
- protected //同一个文件中或子类可见
23-
- public //所有调用的地方都可见
24-
- internal //同一个模块中可见
25-
26-
- abstract //抽象类标示
27-
- final //标示类不可继承,默认属性
28-
- enum //标示类为枚举
29-
- open //类可继承,类默认是final的
30-
- annotation //注解类
31-
- init //主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中
32-
- field //field 标识符只能用在属性的访问器内。特别注意的是,get set方法中只能能使用filed 绝对的。属性访问器就是get set方法。洋气的名字。关于这个我会在后面详细说明
33-
- ://用于类的继承,变量的定义
34-
- .. //范围操作符(递增的) 1..5 2..6 千万不要6..2
35-
- :://作用域限定符,kotlin这个和c语言一样。这个我个人觉得在kotlin中还是很少见的。
36-
- inner //类可以标记为 inner {: .keyword } 以便能够访问外部类的成员。内部类会带有一个对外部类的对象的引用
37-
- object//对象声明 并且它总是在 object{: .keyword } 关键字后跟一个名称。对象表达式:在要创建一个继承自某个(或某些)类型的匿名类的对象会用到
38-
39-
40-
41-
42-
43-
44-
45-
5+
### `Kotlin`用到的关键字
6+
7+
- `var`:定义变量
8+
- `val`:定义常量
9+
- `fun`:定义方法
10+
- `Unit`:默认方法返回值,类似于Java中的void,可以理解成返回没什么用的值
11+
- `vararg`:可变参数
12+
- `$`:字符串模板(取值)
13+
- 位运算符:`or`(按位或),`and`(按位与),`shl`(有符号左移),`shr`(有符号右移),
14+
- `ushr`(无符号右移),`xor`(按位异或),`inv`(按位取反)
15+
- `in`:在某个范围中 检查值是否在或不在(`in/!in`)范围内或集合中
16+
- `downTo`:递减,循环时可用,每次减1
17+
- `step`:步长,循环时可用,设置每次循环的增加或减少的量
18+
- `when`:`Kotlin`中增强版的`switch`,可以匹配值,范围,类型与参数
19+
- `is`:判断类型用,类似于`Java`中的`instanceof()`,`is`运算符检查表达式是否是类型的实例。 如果一个不可变的局部变量或属性是指定类型,则不需要显式转换
20+
- `private`仅在同一个文件中可见
21+
- `protected`同一个文件中或子类可见
22+
- `public`所有调用的地方都可见
23+
- `internal`同一个模块中可见
24+
- `abstract`抽象类标示
25+
- `final`标示类不可继承,默认属性
26+
- `enum`标示类为枚举
27+
- `open`类可继承,类默认是`final`的
28+
- `annotation`注解类
29+
- `init`主构造函数不能包含任何的代码。初始化的代码可以放到以`init`关键字作为前缀的初始化块(`initializer blocks`)中
30+
- `field`只能用在属性的访问器内。特别注意的是,`get set`方法中只能能使用`filed`。属性访问器就是`get set`方法。
31+
- `:`用于类的继承,变量的定义
32+
- `..`围操作符(递增的) `1..5`,`2..6`千万不要`6..2`
33+
- `::`作用域限定符
34+
- `inner`类可以标记为`inner {: .keyword }`以便能够访问外部类的成员。内部类会带有一个对外部类的对象的引用
35+
- `object`对象声明并且它总是在`object{: .keyword }`关键字后跟一个名称。对象表达式:在要创建一个继承自某个(或某些)类型的匿名类的对象会用到
4636

4737

4838
---

‎KotlinCourse/Kotlin学习教程(八).md‎

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,22 @@ val forecastList: RecyclerView = find(R.id.forecast_list)
2727

2828
### Kotlin Android Extensions
2929

30-
相信每一位安卓开发人员对 findViewById() 这个方法再熟悉不过了,毫无疑问,潜在的 bug 和脏乱的代码令后续开发无从下手的。 尽管存在一系列的开源库能够为这个问题带来解决方案,然而对于运行时依赖的库,需要为每一个 View 注解变量字段。
30+
相信每一位安卓开发人员对`findViewById()`这个方法再熟悉不过了,毫无疑问,潜在的`bug`和脏乱的代码令后续开发无从下手的。 尽管存在一系列的开源库能够为这个问题带来解决方案,然而对于运行时依赖的库,需要为每一个`View`注解变量字段。
3131

32-
现在 Kotlin 安卓扩展插件能够提供与这些开源库功能相同的体验,不需要添加任何额外代码,也不影响任何运行时体验。
33-
另一个Kotlin团队研发的可以让开发更简单的插件是Kotlin Android Extensions。当前仅仅包括了view的绑定。这个插件自动创建了很多的属性来让我们直接访问XML中的view。这种方式不需要你在开始使用之前明确地从布局中去找到这些views。
32+
现在`Kotlin`安卓扩展插件能够提供与这些开源库功能相同的体验,不需要添加任何额外代码,也不影响任何运行时体验。
33+
另一个`Kotlin`团队研发的可以让开发更简单的插件是`Kotlin Android Extensions`。当前仅仅包括了`view`的绑定。这个插件自动创建了很多的属性来让我们直接访问`XML`中的`view`。这种方式不需要你在开始使用之前明确地从布局中去找到这些`views`。
3434

35-
这些属性的名字就是来自对应view的id,所以我们取id的时候要十分小心,因为它们将会是我们类中非常重要的一部分。这些属性的类型也是来自XML中的,所以我们不需要去进行额外的类型转换。
35+
这些属性的名字就是来自对应`view`的`id`,所以我们取`id`的时候要十分小心,因为它们将会是我们类中非常重要的一部分。这些属性的类型也是来自`XML`中的,所以我们不需要去进行额外的类型转换。
3636

37-
Kotlin Android Extensions的一个优点是它不需要在我们的代码中依赖其它额外的库。它仅仅由插件组层,需要时用于生成工作所需的代码,只需要依赖于Kotlin的标准库。
37+
`Kotlin Android Extensions`的一个优点是它不需要在我们的代码中依赖其它额外的库。它仅仅由插件组层,需要时用于生成工作所需的代码,只需要依赖于`Kotlin`的标准库。
3838

39-
开发者仅需要在模块的 build.gradle 文件中启用 Gradle 安卓扩展插件即可:
39+
开发者仅需要在模块的`build.gradle`文件中启用`Gradle`安卓扩展插件即可:
4040

41+
```
4142
apply plugin: 'kotlin-android-extensions'
43+
```
4244

43-
44-
默认创建`Kotlin`项目时已经添加了该依赖。
45+
我们在使用`Android Sutdio 3.0`创建`Kotlin`项目时默认已经添加了该依赖。
4546

4647
```kotlin
4748
// 使用来自主代码集的 R.layout.activity_main
@@ -56,21 +57,10 @@ class MyActivity : Activity() {
5657
}
5758
}
5859
```
59-
textView 是对 Activity 的一项扩展属性,与在 activity_main.xml 中的声明具有同样类型。
60-
61-
62-
63-
64-
65-
60+
`textView`是对`Activity`的一项扩展属性,与在`activity_main.xml`中的声明具有同样类型。
6661

6762

68-
69-
70-
71-
72-
73-
### 网络请求
63+
### 网络请求
7464

7565

7666
`Kotlin`提供了一些扩展函数来执行网络请求,同时也可以使用第三方库来执行.
@@ -94,8 +84,8 @@ UIThread有一个很不错的一点就是可以依赖于调用者。如果它是
9484

9585
##### 解析`gson`
9686

97-
Kotlin允许我们去定义一些行为与静态对象一样的对象。尽管这些对象可以用众所周知的模式来实现,比如容易实现的单例模式。
98-
我们需要一个类里面有一些静态的属性、常量或者函数,我们可以使用companion objecvt。这个对象被这个类的所有对象所共享,就像Java中的静态属性或者方法。
87+
`Kotlin`允许我们去定义一些行为与静态对象一样的对象。尽管这些对象可以用众所周知的模式来实现,比如容易实现的单例模式。
88+
我们需要一个类里面有一些静态的属性、常量或者函数,我们可以使用`companion objecvt`。这个对象被这个类的所有对象所共享,就像`Java`中的静态属性或者方法。
9989
```kotlin
10090
public class ForecastRequest(val zipCode: String) {
10191
companion object {
@@ -141,12 +131,12 @@ inline fun <T> with(t: T, body: T.() -> Unit) { t.body() }
141131
- 扩张
142132

143133

134+
参考
135+
===
144136

145-
https://leanpub.com/kotlin-for-android-developers
146-
147-
https://developer.android.com/kotlin/resources.html
148-
149-
https://www.kotlincn.net/docs/reference/coding-conventions.html
137+
- [https://leanpub.com/kotlin-for-android-developers]https://leanpub.com/kotlin-for-android-developers
138+
- [https://developer.android.com/kotlin/resources.html]https://developer.android.com/kotlin/resources.html
139+
- [https://www.kotlincn.net/docs/reference/coding-conventions.html]https://www.kotlincn.net/docs/reference/coding-conventions.html
150140

151141

152142
---

0 commit comments

Comments
 (0)