Skip to content

Commit 8ed165e

Browse files
committed
add notes
1 parent 57aa04b commit 8ed165e

6 files changed

Lines changed: 621 additions & 112 deletions

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Kotlin学习教程(七)
44
这篇文章主要学习下`lambda`表达式。因为后续一些例子会用到。
55

66

7-
> “Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。
7+
> “Lambda 表达式”(lambda expression)其实就是匿名函数,`Lambda`表达式基于数学中的`λ`演算得名,直接对应于其中的`lambda`抽象`(lambda abstraction)`,是一个匿名函数,即没有函数名的函数。`Lambda`表达式可以表示闭包(注意和数学传统意义上的不同)。
88
99
`Java 8`的一个大亮点是引入`Lambda`表达式,使用它设计的代码会更加简洁。
1010

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

Lines changed: 141 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,150 @@ 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-
- `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 }`关键字后跟一个名称。对象表达式:在要创建一个继承自某个(或某些)类型的匿名类的对象会用到
5+
`Kotlin`团队为`Android`开发提供了一套超越标准语言功能的工具:
6+
7+
- `Kotlin Android Extensions`是一个编译器扩展,可以让您摆脱代码中的`findViewById()`调用,并将其替换为合成编译器生成的属性。
8+
- `Anko`是一个提供围绕`Android API``DSL`的一组`Kotlin`友好的包装器,可以用`Kotlin`代码替换`layout .xml`文件。
9+
10+
11+
### `Anko`
12+
13+
[Anko](https://github.com/Kotlin/anko)`Kotlin`官方出品用于`Android`开发的库。
14+
15+
16+
> `Anko is a Kotlin library which makes Android application development faster and easier. It makes your code clean and easy to read, and lets you forget about rough edges of the Android SDK for Java.`
17+
18+
19+
> Anko consists of several parts:
20+
>
21+
> Anko Commons: a lightweight library full of helpers for intents, dialogs, logging and so on;
22+
> Anko Layouts: a fast and type-safe way to write dynamic Android layouts;
23+
> Anko SQLite: a query DSL and parser collection for Android SQLite;
24+
> Anko Coroutines: utilities based on the kotlinx.coroutines library.
25+
26+
27+
一个Anko扩展函数可以被用来简化获取一个RecyclerView:
28+
```kotlin
29+
val forecastList: RecyclerView = find(R.id.forecast_list)
30+
```
31+
32+
33+
34+
### Kotlin Android Extensions
35+
36+
相信每一位安卓开发人员对`findViewById()`这个方法再熟悉不过了,毫无疑问,潜在的`bug`和脏乱的代码令后续开发无从下手的。 尽管存在一系列的开源库能够为这个问题带来解决方案,然而对于运行时依赖的库,需要为每一个`View`注解变量字段。
37+
38+
现在`Kotlin`安卓扩展插件能够提供与这些开源库功能相同的体验,不需要添加任何额外代码,也不影响任何运行时体验。
39+
另一个`Kotlin`团队研发的可以让开发更简单的插件是`Kotlin Android Extensions`。当前仅仅包括了`view`的绑定。这个插件自动创建了很多的属性来让我们直接访问`XML`中的`view`。这种方式不需要你在开始使用之前明确地从布局中去找到这些`views`
40+
41+
这些属性的名字就是来自对应`view``id`,所以我们取`id`的时候要十分小心,因为它们将会是我们类中非常重要的一部分。这些属性的类型也是来自`XML`中的,所以我们不需要去进行额外的类型转换。
42+
43+
`Kotlin Android Extensions`的一个优点是它不需要在我们的代码中依赖其它额外的库。它仅仅由插件组层,需要时用于生成工作所需的代码,只需要依赖于`Kotlin`的标准库。
44+
45+
开发者仅需要在模块的`build.gradle`文件中启用`Gradle`安卓扩展插件即可:
46+
47+
```
48+
apply plugin: 'kotlin-android-extensions'
49+
```
50+
51+
我们在使用`Android Sutdio 3.0`创建`Kotlin`项目时默认已经添加了该依赖。
52+
53+
```kotlin
54+
// 使用来自主代码集的 R.layout.activity_main
55+
import kotlinx.android.synthetic.main.activity_main.*
56+
57+
class MyActivity : Activity() {
58+
override fun onCreate(savedInstanceState: Bundle?) {
59+
super.onCreate(savedInstanceState)
60+
setContentView(R.layout.activity_main)
61+
textView.setText("Hello, world!")
62+
// 而不是 findViewById(R.id.textView) as TextView
63+
}
64+
}
65+
```
66+
`textView`是对`Activity`的一项扩展属性,与在`activity_main.xml`中的声明具有同样类型。
67+
68+
69+
### 网络请求
70+
71+
72+
`Kotlin`提供了一些扩展函数来执行网络请求,同时也可以使用第三方库来执行.
73+
```kotlin
74+
public class Request(val url: String) {
75+
public fun run() {
76+
val forecastJsonStr = URL(url).readText()
77+
Log.d(javaClass.simpleName, forecastJsonStr)
78+
}
79+
}
80+
```
81+
82+
如你所知,HTTP请求不被允许在主线程中执行,否则它会抛出异常。这是因为阻塞住UI线程是一个非常差的体验。Android中通用的做法是使用AsyncTask,但是这些类是非常丑陋的,并且使用它们无任何副作用地实现功能也是非常困难的。Anko提供了非常简单的DSL来处理异步任务,它满足大部分的需求。它提供了一个基本的async函数用于在其它线程执行代码,也可以选择通过调用uiThread的方式回到主线程。在子线程中执行请求如下这么简单:
83+
```kotlin
84+
async() {
85+
Request(url).run()
86+
uiThread { longToast("Request performed") }
87+
}
88+
```
89+
UIThread有一个很不错的一点就是可以依赖于调用者。如果它是被一个Activity调用的,那么如果activity.isFinishing()返回true,则uiThread不会执行,这样就不会在Activity销毁的时候遇到崩溃的情况了。
90+
91+
##### 解析`gson`
92+
93+
`Kotlin`允许我们去定义一些行为与静态对象一样的对象。尽管这些对象可以用众所周知的模式来实现,比如容易实现的单例模式。
94+
我们需要一个类里面有一些静态的属性、常量或者函数,我们可以使用`companion objecvt`。这个对象被这个类的所有对象所共享,就像`Java`中的静态属性或者方法。
95+
```kotlin
96+
public class ForecastRequest(val zipCode: String) {
97+
companion object {
98+
private val APP_ID = "15646a06818f61f7b8d7823ca833e1ce"
99+
private val URL = "http://api.openweathermap.org/data/2.5/" +
100+
"forecast/daily?mode=json&units=metric&cnt=7"
101+
private val COMPLETE_URL = "$URL&APPID=$APP_ID&q="
102+
}
103+
104+
fun execute(): ForecastResult {
105+
val forecastJsonStr = URL(COMPLETE_URL + zipCode).readText()
106+
return Gson().fromJson(forecastJsonStr, ForecastResult::class.java)
107+
}
108+
}
109+
```
110+
111+
112+
### 创建Application
113+
114+
```kotlin
115+
class App : Application() {
116+
companion object {
117+
private var instance: Application? = null
118+
fun instance() = instance!!
119+
}
120+
override fun onCreate() {
121+
super.onCreate()
122+
instance = this
123+
}
124+
}
125+
126+
```
127+
128+
129+
130+
131+
- with()
132+
133+
```kotlin
134+
inline fun <T> with(t: T, body: T.() -> Unit) { t.body() }
135+
```
136+
137+
138+
139+
参考
140+
===
141+
142+
- [Kotlin for Android Developers](https://leanpub.com/kotlin-for-android-developers)
143+
- [Resources to Learn Kotlin](https://developer.android.com/kotlin/resources.html)
144+
- [Kotlin语言中文站](https://www.kotlincn.net/docs/reference/coding-conventions.html)
36145

37146

38147
---
39148

40149
- 邮箱 :charon.chui@gmail.com
41150
- Good Luck!
151+

KotlinCourse/Kotlin学习教程(五).md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,44 @@ val searchPosition: Int = Icon.SEARCH.ordinal()
155155

156156
```
157157

158+
### 密封类
159+
160+
密封类用来表示受限的类继承结构:当一个值为有限集中的
161+
类型、而不能有任何其他类型时。在某种意义上,他们是枚举类的扩展:枚举类型的值集合
162+
也是受限的,但每个枚举常量只存在一个实例,而密封类
163+
的一个子类可以有可包含状态的多个实例。
164+
165+
要声明一个密封类,需要在类名前面添加`sealed`修饰符。虽然密封类也可以
166+
有子类,但是所有子类都必须在与密封类自身相同的文件中声明。(在`Kotlin 1.1`之前,
167+
该规则更加严格:子类必须嵌套在密封类声明的内部)。
168+
169+
```kotlin
170+
sealed class Expr
171+
data class Const(val number: Double) : Expr()
172+
data class Sum(val e1: Expr, val e2: Expr) : Expr()
173+
object NotANumber : Expr()
174+
175+
fun eval(expr: Expr): Double = when (expr) {
176+
is Const -> expr.number
177+
is Sum -> eval(expr.e1) + eval(expr.e2)
178+
NotANumber -> Double.NaN
179+
}
180+
```
181+
182+
使用密封类的关键好处在于使用`when`表达式 的时候,如果能够
183+
验证语句覆盖了所有情况,就不需要为该语句再添加一个`else`子句了。
184+
185+
```kotlin
186+
fun eval(expr: Expr): Double = when(expr) {
187+
is Expr.Const -> expr.number
188+
is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
189+
Expr.NotANumber -> Double.NaN
190+
// 不再需要 `else` 子句,因为我们已经覆盖了所有的情况
191+
}
192+
```
193+
194+
195+
158196
### 异常
159197

160198
`Kotlin`中,所有的`Exception`都是实现了`Throwable`,含有一个`message`且未经检查。这表示我们不会强迫我们在任何地方使用`try/catch`。这与`Java`中不太一样,比如在抛出`IOException`的方法,我们需要使用`try-catch`包围代码块。但是通过检查`exception`来处理显示并不是一个好的方法。
@@ -256,7 +294,7 @@ class App : Application() {
256294

257295
##### 类委托
258296

259-
委托模式是最常用的设计模式的一种,在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。kotlin中的委托可以算是对委托模式的官方支持
297+
委托模式是最常用的设计模式的一种,在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。`kotlin`中的委托可以算是对委托模式的官方支持
260298
`Kotlin`直接支持委托模式,更加优雅,简洁。`Kotlin`通过关键字`by`实现委托。
261299

262300
```kotlin

0 commit comments

Comments
 (0)