Các mẹo nhỏ bạn nên biết khi dùng Kotlin (P1)
Bài đăng này đã không được cập nhật trong 7 năm
Bạn sử dụng Kotlin để lập trình ứng dụng Android? Bạn nghe nói dùng Kotlin code rất nhanh, có thật sự vậy không? Bạn muốn sử dụng tối đa sự hữu dụng của ngôn ngữ lập trình này? Vậy sau đây là các mẹo nhỏ, khi bạn dùng nó chắc chắn bạn sẽ thấy sức mạnh của Kotlin mang tới cho bạn các dòng code thực sự rất ngắn!!!
#1 Explosive Placeholders Rất nhiều lần khi bạn implement một class mới, bạn sẽ được hỗ trợ các method TODO, ví dụ như:
class Test : Runnable {
override fun run() {
// TODO doSomethingElse()?
}
}
Nó rất hữu dụng khi bạn làm theo flow, IDE sẽ cảnh báo bạn khi có case nào đó bạn quên chưa làm. Nhưng nếu như bạn chỉ muốn đánh dấu là phần đó mình sẽ làm trong tương lai, bạn sẽ phải code rất nhiều thứ, đại loại như là:
class Test : Callable<String> {
override fun call(): String {
if (something()) {
return doSomething()
} else {
throw UnsupportedOperationException("TODO return doSomethingElse()?")
}
}
}
Nhưng Kotlin sẽ giúp bạn làm điều đó rất đơn giản, bạn chỉ cần:
class Test : Callable<String> {
override fun call(): String {
if (something()) {
return doSomething()
} else {
TODO("doSomethingElse()?")
}
}
}
#2 Semantic Validation
Khi bạn muốn validate tham số truyền vào, ở đây mình ví dụ String sep
, và show ra các throw thông báo tương ứng.
Với Java
bạn sẽ phải làm đại loại như sau:
public String join(String sep, List<String> strings) {
if (sep == null) throw new NullPointerException("sep == null");
if (sep.length() < 2) {
throw new IllegalArgumentException("sep.leng() < 2: "+sep);
}
if (strings == null) throw new NullPointerException("string == null");
//....
}
Hoặc bạn có thể dùng Guava
với Preconditions
để validate điều kiện nhập vào, ví dụ như:
public String join(String sep, List<String> strings) {
Preconditions.checkNotNull(sep, "sep == null");
Preconditions.checkArgument(sep.length() < 2, "sep.leng() < 2: "+sep);
Preconditions.checkNotNull(strings, "string == null");
//....
}
Nhưng với Kotlin bạn không phải check nhiều như vậy, hệ thống sẽ tự check cho bạn phần null
fun join(sep: String, strings: List<String>): String {
Preconditions.checkArgument(sep.length < 2, "sep.leng < 2: " + sep)
//...
}
Trong Kotlin, Preconditions
cũng được viết ngắn gọn thành:
fun join(sep: String, strings: List<String>): String {
require(sep.length < 2) { "sep.length < 2: " + sep}
//...
}
#3 Let
Trong Kotlin có 2 từ khóa cơ bản là var
và val
.
Từ khóa val
sử dụng khi giá trị của biến không thay đổi
val user: User? = null
if (user != null) {
//user not null
}
Từ khóa var
sử dụng khi giá trị của biến thay đổi
var user: User? = null
if (user != null) {
//user might be null
}
Ta có thêm từ khóa khác là let
, bằng việc sử dụng let
, các biến trong block sẽ đảm bảo không thể null, bạn không cần phải thêm dấu ?
nữa
var user: User? = null
user?.let {
// it == user not null, only read once
}
Bên trong block của let
, bạn có thể dùng nhiều reference nếu bạn muốn
class Foo {
@Volatile
var user: User? = null
fun doSomething() {
user?.let { user ->
//user not null, only read once!
}
}
}
Bên cạnh đó, khi chúng ta gọi 1 hàm và muốn sử dụng giá trị trả về của nó nhiều lần, ta cũng có thể sử dụng let
someMethod().let { result ->
//use result multiple times
}
#4 Multiline String Literals
Khi chúng ta có 1 String có chứa nhiều dòng, ở Java ta phải sử dụng toán tử \n
val string = "foo\nbar\nbaz"
hoặc
val string = "foo\n"
+"bar\n"
+"baz"
Bạn không phải làm những điều như vậy trong Kotlin, với việc chỉ cần thêm nháy " ở trước dòng đầu tiên và sau dòng cuối cùng.
val string = """foo
bar
baz"""
Hoặc sử dụng các lệnh trim
val foo = "FOO!"
val bar = "BAR!"
val baz = "BAZ!"
val string = """|$foo
|$bar
|$baz""".trimMargin()
#5 Name your import Khi có Conflict, đặc biệt về việc thay đổi tên class dẫn đến import sai, chắc chắn là sẽ rất mất thời gian để fix lại Ví dụ như:
package com.kotlinexample.ui
import ...
import android.view.View // Conflict
class UserInfoFragment : Fragment(), com.kotlinexample.ui.View { // Conflict
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
state: Bundle?): View = // Conflict
inflater.inflate(user_info_fragment,
container,
false)
}
interface View // Conflict
Nhưng với Kotlin, bạn có thể đặt tên cho import và dùng nó trong class, khi đó thì mọi việc sẽ trở nên rất đơn giản
import android.view.View as AndroidView // Named import
class UserInfoFragment : Fragment(), View {
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
state: Bundle?): AndroidView = // Using named import
}
Vẫn còn rất nhiều những mẹo nhỏ bạn có thể dùng để việc sử dụng Kotlin trở nên thú vị hơn, mình sẽ giới thiệu tiếp ở các phần sau. Chúc các bạn code vui vẻ!
All rights reserved