Kotlin开始
- 二、习惯用法
- 1、创建 DTOs(POJOs/POCOs)
- 2、函数默认参数
- 3、过滤 list
- 4、字符串插值
- 5、实例检查
- 6、遍历 map/list 键值对
- 7、使用 ranges
- 8、只读 list和只读map
- 9、访问 map
- 10、懒属性(延迟加载)
- 11、扩展函数
- 12、创建单例模式
- 13、null空值判断和操作符
- 14、三种表达式
- 15、返回类型为 Unit 的方法的 Builder 风格用法
- 16、单表达式函数
- 17、对一个对象实例调用多个方法
- 18、配置对象的属性(apply)
- 19、Java 7 的 try with resources
- 20、对于需要泛型信息的泛型函数的适宜形式
- 21、使用可空布尔
- 22、交换两个变量
- 23、TODO():将代码标记为不完整
二、习惯用法
1、创建 DTOs(POJOs/POCOs)
1)dto=data transfer object,数据传输对象。就是那些只用来保存数据的一些类。
2)在类的前面加上"data"
data class Customer(val name: String, val email: String)
//因为是只用来保存数据,所以变量使用val:不可变的变量
3)普通java对象(POJO)=Plain Old Java Object。普通旧CLR对象(POCO)=Plain Old CLR Object,或者plain old clrclass object?。表示最原始的class,仅从object继承。CLR=common language runtime,公共语言运行库
2、函数默认参数
1)函数名放入输入值时,就赋一个初始值。
fun foo(a: Int = 0, b: String = "") { ... }
//在这个foo函数里面,给a和b分别赋值为0和null
3、过滤 list
val positives = list.filter { it > 0 }
//对list进行过滤filter,过滤出其中每一个大于零的成员
4、字符串插值
println("Name $name")
//非常常用!!!美元符号$就是取值的意思
5、实例检查
when (x) {
is Foo -> ...
is Bar -> ...
else -> ...
}
//就是加了一个is判断,
6、遍历 map/list 键值对
//input
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
fun main(){
println(map)
for ((k, v) in map) {
print("$k -> $v")
print(';')
}
}
//output
//[a, b, c]
//{a=1, b=2, c=3}
//a -> 1;b -> 2;c -> 3;
//在print里面的->,不需要用引号括起来,就可以直接像字符串一样输出
7、使用 ranges
for (i in 1..100) { ... } // 闭区间: 包括100
for (i in 1 until 100) { ... } // 半开区间: 不包括100
for (x in 2..10 step 2) { ... }
for (x in 10 downTo 1) { ... }
if (x in 1..10) { ... }
只能左闭右闭,或者左闭右开。左边一定闭,右边默认闭,加上until,就变成开。
8、只读 list和只读map
1)list。
val list = listOf("a", "b", "c")
2)map。
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
9、访问 map
//input
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
fun main(){
print(map["a"])
}
//output
//1
10、懒属性(延迟加载)
1)将对象的加载延迟到我们需要它的时候。简而言之,按需加载对象而不是不必要地加载对象。
2)例子
val p: String by lazy {
// compute the string
}
11、扩展函数
open class Animal {
open fun shout() = println("animal is shout")//定义成员函数
}
class Cat: Animal() {
override fun shout() {
println("Cat is shout")//子类重写父类成员函数
}
}
//定义子类和父类扩展函数
fun Animal.eat() = println("Animal eat something")
fun Cat.eat()= println("Cat eat fish")
//测试
fun main(args: Array<String>) {
val animal: Animal = Cat()
println("成员函数测试: ${animal.shout()}")
println("扩展函数测试: ${animal.eat()}")
}
12、创建单例模式
object Resource {
val name = "Name"
}
13、null空值判断和操作符
1)?.和?:的区别
(1)?. = If Not Null
code1?.code2 翻译为 :if code1 Not Null 执行 code2; ,
(2)?: = If Not
code1?:code2 翻译为:if code1 Null 执行 code2;
(3)?. ?: = If not null and else
code1?.code2 ?:code3翻译为:if code1 不是Null 则执行 code2;如果是Null,则执行code3。
2)其他用法
(1)在可能会空的集合中取第一元素
val emails = …… // 可能会是空集合
val mainEmail = emails.firstOrNull() ?: ""
(2)if not null 执行代码
val value = ……
value?.let {
…… // 代码会执行到此处, 假如data不为null
}
(3)if not null 执行代码
val value = ……
val mapped = value?.let { transformValue(it) } ?: defaultValue
// 如果该值或其转换结果为空,那么返回 defaultValue。
14、三种表达式
1)返回 when 表达式
直接在大括号里面的when前面,加上return即可
fun transform(color: String): Int {
return when (color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalArgumentException("Invalid color param value")
}
}
2)“try/catch”表达式
普通的异常处理
fun test() {
val result = try {
count()
} catch (e: ArithmeticException) {
throw IllegalStateException(e)
}
// 使用 result
}
3)“if”表达式
普通的if else判断语句
fun foo(param: Int) {
val result = if (param == 1) {
"one"
} else if (param == 2) {
"two"
} else {
"three"
}
}
15、返回类型为 Unit 的方法的 Builder 风格用法
fun arrayOfMinusOnes(size: Int): IntArray {
return IntArray(size).apply { fill(-1) }
}
类似于这种,.apply{}里面放进去参数,就叫做builder风格。因为有种用法是.build{}
16、单表达式函数
fun theAnswer() = 42
//一个函数,直接等于一个值
等价于
fun theAnswer(): Int {
return 42
}
//和使用return返回一个值是相同的
和其他用法一起使用
fun transform(color: String): Int = when (color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalArgumentException("Invalid color param value")
}
上面的代码,不是直接等于一个数,而是变成了等于一个when表达式
17、对一个对象实例调用多个方法
class Turtle {
fun penDown()
fun penUp()
fun turn(degrees: Double)
fun forward(pixels: Double)
}
val myTurtle = Turtle()
with(myTurtle) { // 画一个 100 像素的正方形
penDown()
for (i in 1..4) {
forward(100.0)
turn(90.0)
}
penUp()
}
在with()里面加上你创建的那个实例的名字,然后就可以在with(实例){}的大括号里面,写上这个实例的“多个方法”。
18、配置对象的属性(apply)
val myRectangle = Rectangle().apply {
length = 4
breadth = 5
color = 0xFAFAFA
}
在apply的大括号{}里面,给各个参数赋值。
19、Java 7 的 try with resources
Java语法糖 : 使用 try-with-resources 语句安全地释放资源
20、对于需要泛型信息的泛型函数的适宜形式
// public final class Gson {
// ……
// public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
// ……
inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)
和Java一样,Kotlin也提供了对泛型的支持,即允许定义 类型形参。 在执行的过程中,类型形参将会转变为类型实参的具体类型。 在Kotlin中声明泛型函数 如果想编写一个对于任何类型都有效的函数,可以声明泛型函数。 其步骤为先 申明类型形参 ,然后在接收者或者返回类型中 使用类型形参 。
21、使用可空布尔
val b: Boolean? = ……
if (b == true) {
……
} else {
// `b` 是 false 或者 null
}
就像上面这个,把布尔值,设置为var可变的
22、交换两个变量
var a = 1
var b = 2
a = b.also { b = a }
直接用这个.also,就不用使用第三个变量来储存其中一个值了
23、TODO():将代码标记为不完整
Kotlin 的标准库有一个 TODO() 函数,该函数总是抛出一个 NotImplementedError。 其返回类型为 Nothing,因此无论预期类型是什么都可以使用它。 还有一个接受原因参数的重载:
fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")
IntelliJ IDEA 的 kotlin 插件理解 TODO() 的语言,并且会自动在 TODO 工具窗口中添加代码指示。