Advanced Kotlin Tips for developers
Bài đăng này đã không được cập nhật trong 7 năm
Advanced Kotlin Tips về việc viết code và sử dụng những gì Kotlin cung cấp có rất nhiều lời ích. Có rất nhiều lợi ích của việc sử dụng Kotlin: súc tích, an toàn, và quan trọng là nó interoperable với Java. Kotlin cũng giải quyết rất nhiều vấn đề hạn chế trong Java. Nên bài viết này giới thiệu một số Advanced Kotlin Típ giúp mọi người bắt đầu sử dụng và viết code tốt hơn với Kotlin.
1. Singleton
Thực hiện lazy loaded và thread-safe singleton
in Kotlin rất đơn giản, không giống như Java là phải dựa vào mô hình khóa kiểm tra tương đối phức tạp double-checked looking pattern.
object Singleton {
var s: String? = null
}
Singleton
trong Kotlin không cần constructor, nhưng method init
có thể được sử dụng để khởi tạo nếu cần thiết.
Singleton.s = "test" // class is initialized at this point
2. Utility Functions
Hỗ trợ mở rộng các hàm của Kotlin thông qua các lớp tiện ích Java. Và dễ dàng tiêu thụ hơn trong việc sử dụng mã Java @file:JvmName()
để xác định tên của Java class sẽ được tự động sinh ra bởi Kotlin compiler.
// Use this annotation so you can call it from Java code like StringUtil.
@file:JvmName("StringUtil")
fun String.lengthIsEven(): Boolean = length % 2 == 0
val lengthIsEven = "someString".lengthIsEven()
3. Object Initialization
Sử dụng apply
cho các câu lệnh khởi tạo để đọc code dễ dàng hơn.
// Don't
val textView = TextView(this)
textView.visibility = View.VISIBLE
textView.text = "test"
// Do
val textView = TextView(this).apply {
visibility = View.VISIBLE
text = "test"
}
4. Một vài Kotlin tips nhỏ cho bạn!
let
Sử dụnglet
thay thế cho hàmif()
. Kiểm trả đoạn code sau:
val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
if (item != null) {
println(item!!)
}
}
Với sử dụng let
thay thế cho if()
val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
item?.let { println(it) } // prints A and ignores null
}
When()
When()
thay thế choswitch
operator của Java và nó có clean hơn là sử dụng if conditions
// Java
public Product parseResponse(Response response) {
if (response == null) {
throw new HTTPException("Something bad happened");
}
int code = response.code();
if (code == 200 || code == 201) {
return parse(response.body());
}
if (code >= 400 && code <= 499) {
throw new HTTPException("Invalid request");
}
if (code >= 500 && code <= 599) {
throw new HTTPException("Server error");
}
throw new HTTPException("Error! Code " + code);
}
Sử dụng when
// Kotlin
fun parseResponse(response: Response?) = when (response?.code()) {
null -> throw HTTPException("Something bad happened")
200, 201 -> parse(response.body())
in 400..499 -> throw HTTPException("Invalid request")
in 500..599 -> throw HTTPException("Server error")
else -> throw HTTPException("Error! Code ${response.code()}")
}
5. Read-only List, Map...
Kotlin phân biệt giữa Mutable và Immutable collections(list, map, set...). Kiểm soát chính xác collections rất hữu ích để loại bỏ lỗi và thiết kế các API tốt.
Library của Kotlin chứa các hàm tiện ích cho cả mutable
và immutable
collections. Ví dụ listOf()
và mutableListOf()
val list = listOf(“a”, “b”, “c”)
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
6. Lazy Property
lazy
is good, nó giúp tiết kiệm bộ nhớ và tiết kiệm chu kỳ CPU nếu khởi tạo của nó expensive.
val str: String by lazy {
// Compute the string
}
7. Local functions
Local functions are good cho việc tái sử dụng, cẩn thận sử dụng để tránh lạm dụng.
fun foo(a: Int) {
fun local(b: Int) {
return a + b
}
return local(1)
}
8. Infix functions
Infix functions are good, nó giúp cho chúng ta dễ dàng đọc code, bởi vì nó cho phép nhập một số thứ như "test" foo "x" ví dụ:
infix fun String.foo(s: String) {
...
}
// Call extension function.
"test".foo("x")
// Or call extension function using infix notation.
"test" foo "x"
Infix function chỉ sử dụng cho function có 1 parameter
9. Inline functions
Lambda expression trong Kotlin được dịch sang lớp ẩn danh trong Java 6 hoặc 7. Lambda tác động tăng hiệu suất.
inline
functions được sử dụng để thay thế các phương thức khác và thêm vào đó call stack vì vậy nó có ý nghĩa là thêm đoạn code trong inline function cho chỗ gọi chúng
inline fun callBlock(block: () -> Unit) {
println("Before calling block")
block()
println("After calling block")
}
Khi chúng ta gọi phương thức **callBlock**
nó sẽ được dịch như dưới đây:
callBlock { println("The block operation") }
// Rough java bytecode
String var1 = "Before calling block";
System.out.println(var1)
String var2 = "The block operation";
System.out.println(var2);
var1 = "After calling block";
System.out.println(var1);
Với functions không phải là inline functions
callBlock { println("The block operation") }
// Rough java bytecode
callBlock((Functinos0)null.INSTANCE);
Chú ý: không nên sử dụng inline
function khi mà đoạn code trong inline functions quá lớn
10. Tail recursion
Khi sử dụng tailrec
chúng tôi cho phép compiler biết rằng nó có thể thay thế các method với for loop hoặc goto stament
tailrec fun findFixPoint(x: Double = 1.0): Double
= if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))
```
All rights reserved