2018年8月28日 星期二

Kotlin 的 annotation

annotation 顧名思義很像是當註解用,但跟 // ... 或 /*  ...   */  隨意寫內容的註釋(commnet)並不同,它有自成一套的運作機制,可以用來定義自己喜歡的註解方式,規定如何來寫註解,搭配Kotlin 內建的註解 @TAGET 可以限制註解的標地物,甚至還可以引進一些 meta-date,因此 annotation 可說是具有運作功能(function)的註解,因此才會自成一類稱之為  annotation class (註解類別).
自定註解類別若配合建構式可以規定要如何撰寫註解,運用時只要簡單加上 @註解類別 (例如 Kotlin 內建的 @TARGET), 但是當程式引用的方式不對時,編譯器就會出現錯誤警告訊息.以下示範定義一個 "無意義註解",當然也可以自訂 "有無意義註解"讓程式碼更具可讀性:
             annotation  class     無意義註解             // 制定一個類別名稱是: 無意義註解
            @無意義註解       
            fun main(args: Array < String >  ) {               
                println( "Hello" )
            }
上述程式裡註解看似無任何意義,但可以完成正常編譯程序並執行, 現在搭配建構式,制定一個必須寫字串的註解,Kotlin 對於類別的建構式,當它含有預設參數值時,呼叫時就可以免輸入參數而使用預設值
     annotation class 註解(val why:String="預設註解")   //  含預設參數建構式的 "註解"
     @註解("這是一個範例程式")      // 有建構式, 可以傳參數進去並呼叫 "註解"
     fun main(args: Array < String >  ) {
              @註解 { println("列出訊息")  }   // 已有預設值可免傳參數, 註解作用在 λ ,合法但 { } 內容卻不會執行
               println("Hello")
      }
上述程序可以正常編譯並執行,但如果 @註解 傳進去的是一個非字串型態的參數,編譯器就會抱怨,定義註解類別有許多規定, 它限制建構式必須用 val 宣告輸入變數,註解的標的物也有規則的,像  @註解 println("Hello") 就不合法, 但作用在 lambda(希臘字母 λ) 函式像是  @註解 {   }  卻是合法的, 只是編譯會產生警告訊息並且 { } 裏面的 λ 函式可能不會執行.如果在註解類別內引用定義過的註解時,就不用加上 @,例如:
     annotation class 註解(val why:String="預設值")   //  含預設參數建構式的 "註解"
     annotation class 注意註解(val warring:String, val note:註解 = 註解("新的預設值") ) // 新的註解類別引用上述的 "註解" 類別時不需加 @
     @註解("這是一個範例程式")      // 傳參數並呼叫 "註解"
     @注意註解("注意",註解("注意這是新的註解"))  // 呼叫 "注意註解"
     fun main(args: Array < String >  ) {
              @註解  { println("列出訊息")  }   // 註解作用在 λ ,合法但 { } 內容卻不會執行
               println("Hello")
               @注意註解("注意")  var f= "evaluated"  // 註解作用在屬性值, 該賦值還是會被執行
                println("f  is  $f");                                       // 印出  f 看看
      }
 上述只是粗淺的用法, 實際上 annotation class 可以更複雜使用, 其奧妙之深尚需了解中

沒有留言: