4
javac could be silently modified to make void methods return self (twitter.com)
IngramChen 積分 4 編輯於

a long story...

Java 現況:

 //Java10
 var rect = new Rectangle();
 rect.setX(12);
 rect.setY(10);
 rect.setWidth(300);

如果照這個 tweet 的說法,那就可以這樣寫:

 //Java++
 var rect = new Rectangle()
               .setX(12)
               .setY(10)
               .setWidth(300);

看起來好像挺不賴的?不過這有個很大的缺點: 讀程式碼的人會誤以為 .setFoo() 有回傳自己,而不是 void。Java 就是因為沒有這種潛規則所以才好讀好維護的,我個人是不願意見到這種魔改。

取而代之,應該可以借用 Dartcascade operator1

 //Dart code
 var rect = new Rectangle()
               ..setX(12)
               ..setY(10)
               ..setWidth(300);

變成 .. 就代表該 statement 會回傳自己。這在 Dart 上已經用了超過五年了,沒看到什麼負評。然後也因為有這個 operator,在 Dart 裡沒有人寫 builder pattern。大家在設計 API 時,都會認為開發者會應用 cascade operator。

如果未來 Java 不是靠新的 operator,而是靠加了 compiler 潛規則回傳 this,那還真是慘,到時就只能靠 IDE 上色幫忙了 (void 當 this 回傳時,前面那個 . 變成又紅又大 這樣)

那 Kotlin 呢?Kotlin 裡是這樣玩的:

 //Kotlin
 val rect = Rectangle().apply {
   x = 12
   y = 10
   width = 300
 }

hmm... Kotlin 裡好像多了幾個字,和一個大括號,感覺起來很囉嗦?

非也,我個人最愛 Kotlin 的設計,那個 .apply() 可不是語言的語法,那只是個 library,它靠著 Kotlin 語言內建的 extension method 和 inline lambda 兩個功能就兜出來了,不用玩花樣魔改。如果 receiver 是 null,整個 block 還可以跳過:

 //Kotlin
 fun updateDimension(rect:Rectangle?) {
   rect?.apply {
     x = 12
     y = 10
     width = 300
   }
 }

加個 ?. 就可以安全避開 null pointer exception。

Kotlin 最棒的就是語言提供很簡單,但是又強大的功能,讓更進階的 語法 都可以靠 library 實現,so powerful, so elagant!