調べてもよく理解できない、覚えられないということで自分でまとめてみる。
早速本題へ
kotlin歴短いので、ご指摘等どうぞ
##apply vs run ##
val menuFile = File("text.txt").apply{
setReadable(true) // this.setReadable(true) と同じ
setWritable(true) // this == File("text.txt")
}
オブジェクト生成時に使う。
File("text.txt")をapplyの中ではthisとして扱うことができて、もちろん省略もできる。
戻り値はthis
apply使ってないバージョン
val menuFile = File("text.txt")
menuFile.setReadable(true)
menuFile.setWritable(true)
val hasPath = File("xxx.txt").run{
readText().contains("hello") // this == File("xxx.txt")
}
applyと同じくrunの中でthisを扱える
applyは呼び出し元を返すのに対し、runはラムダの結果を返す。
##let vs also ##
fun getHello(name :String?):String{
return name?.let{
"hello ${it}" // nameがmasakiの場合は hello masakiになる
}?:" hello world" // nameがnullの場合は hello world
}
letの中ではnameをitで扱える。
letの中の最後の文が返り値となる。
let使ってないバージョン
fun getHello(name :String?):String{
return if(name != null){
"hello ${it}"
}else{
"hello world"
}
}
var fileContents:String?
File("xxx.txt").also{
plint(it.name) // xxx.txtが出力される
}.also{
fileContents = it.readLine()
}
letと同じくitでFile("xxx.txt")を扱える。
letとの違いはletはラムダの結果を返すが、alsoは呼び出し元(ここではFile("xxx.txt"))を返すので、Chain化可能
##with##
runと同じだけど呼び出し方が違うだけ
他の関数と呼び出し方が違うので使わないほうが良さそう
val len = with("hello"){
length
}
##takeIf##
val fileContent = File("xxx.txt")
.takeIf{it.canRead() && it.canWrite()}
?.readText()
Fileをitで受け取り
takeIfがtrueならitを返す。結果としてreadText()がfileContentに入る。
takeIfがfalseならnullを返す
##takeUnless##
class Status(val error: Boolean){
fun isError():Boolean{
return error
}
}
fun process():Status?{
val result = Status(false) //falseの場合は resultを返す。
//val result = Status(true) //true の場合は nullを返す。
return result.takeUnless { it.isError() }
}
takeIfの逆でfalseならならitを返す。
上記の例はisError()がfalseの場合は結果を返し、trueの場合はnullを返す。
最後に
基本的にもうちょっとコード量を少なくするための関数だと思います。
覚えないとコードがかけないってのはないけど、
他人が書いたソースを読む際には必要になってくるでしょうね。