Kotlin從入門到精通(補充中

一.處理Kotlin代碼的方式

1.Kotlin Playgroud         在對應網站trykotlinlang.org上在線試用,不用Andriod框架依賴性

2.Andriod Studio |File|Setting|Plugins|Install JetBrains plugin..|Kotlin下載在2.x版本下,3.x則不用,在Tools|Kotlin|Configuration Kotlin in Project

       選擇Andriod with  Gradle 然後再選擇所需模塊和Kotlin版本,3.0之後可在創建項目時選中Include Kotlin support

 

 

3.使用Java-Kotlin轉換器J2K

二.Kotlin語言基礎知識

1.Kotlin 定義兩種數據類型: var:可變引用,可在初始化後更新

                                              val:只讀引用,初始化之後無法賦值

val變量相當與final修飾的Java變量,防止被錯誤修改,多線程工作時,可以不必擔心數據同步操作,@val無法改變指向特定對象實例的引用,但可以修改對象的屬性

var list = mutableListOf("a","b","c")//ok
list = mutableListOf("d")//error
list.remove(3)//ok

2.類型推斷

var title :String

當變量聲明和初始化一起執行,可忽略類型聲明

var title:String="Kotlin"

類型推斷會導致title = 12報錯

Kotlin有類型體系結構,全部顯性繼承Any類型,相當與Java的對象,有equals、toString、hashCode

在Android Studio中可以用Shift+Ctrl+P快捷鍵知道類型,類型推薦機制同樣可以用於泛型

var persons = listOf(personInstancel1,personInstancel2)
//equal to List<Person>
var pair = "Everest" to 8848
//equal to Pair<String,Int>
var pair = Pair("Ever",8848)
//use constructor
   二元參數判斷取基本類型String和Int最近的Any類型

必要時可以顯性定義數據類型var age: Long = 18

省內存可以用Short

3.嚴格的空保護機制

在Java中的NullPointerExceptions,大多數不是運行期錯誤,所以Kotlin加入默認情況下不能設置爲空值和存儲空引用,除非顯性定義

//在變量類型聲明加?
val age:Int = null//error
val name:String? =null//ok
//但是潛在空對象無法調用其方法
name.toUpperCase()//error
//需要在調用前加判斷

3.Kotlin安全調用 val locked: Bollean? = savedInstanceState?.getBoolean("locked")

4.elvis操作符 first operand?:second operand 如果第一個操作數不爲null返回否則第二個

5.let 可空變量處理方式

savedInstanceState?.let{

//ok
}
//當不爲空執行let之後的代碼

6.處理空指針的例子

val textView = findViewById(R.id.textView) as TextView//不可空

val textView = findViewById(R.id.textView) as TextView?//可空

7.轉換

Kotlin採用as關鍵字爲轉換操作符,處理轉換問題

val fragment: Fragment = ProductFragment()

val productFragment: ProductFragment = fragment as ProductFragment//將上面的fragment轉變成ProductFragment

非安全型轉換as:無法實現,拋出ClassCastException異常

安全型轉換 as?:無法實現,返回null

Kotlin支持to+類型名

智能轉換   隱性轉換 

//Fish繼承Animal並有自己的方法isHungry()
if(animal is Fish){

                 animal.isHungey()//此時爲fish


             }

                animal.isHungey()//error 此時爲animal

在&&和判空可以應用

fun setView(view :View?){
    view ?:throw RunTimeExceptions("View is empty")
    //is non-nullable
    view.isShown()
}

8.基本數據類型

Byte?、Char?,爲"裝箱"型表達方式,但是這種方式比較耗內存,對錶和數組來講,影響尤爲明顯,對於單變量來說就不用擔心表達形式

Kotlin針對數字的處理方式不同,數字間沒有隱式轉換,較小的類型不能隱式轉變爲較大類型

var weight: Int = 12
var truckweight: Long = weight//error
var truckweight: Long = weight.toLong()
//正確形式


//Kotlin 可以推斷類型
val a: Int =1
val b =a+1 //inferred b is Int
val b = a+1L //inferred b is Long 

Kotlin 不支持8進制

9.數組

val array = arrayOf(1,2,3)
//建立數組
val array2:Array<Short> = arrayOf(1,2,3)
val array3:Array<Long> = arrayOf(1,2,3)


val array = arrayOf(1,2,3)//Long數據元素的泛型數組
val array = longArrayOf(1,2,3)//包含Long 數據元素的數組

//kotlin可以指定數組的實際尺寸
val array = arrayOfNulls(3)

val array = Array(5){it*2}//lambda表達式
println(array)  // Prints: [ 0,2,4,8,10] 

10.字符串

方法可以參考String類文檔

val name = "Eva"
val message = "My name is $name"
//$符號將變量置於字符串之中
val message = "My name has ${name.length} characters"

11.數組遍歷

val intRange = 1..4//equal to i>=1&&i<=4
val charRange = 'b' .. 'g'

默認步進值爲1
for(i in 5 downTo 1) print(i) // 逆向遍歷
for(i in 3..6 step 2) print(i)//Prints:35
step設置步長

12.Kotlin爲面向表達式語言 var speed = vcurrentSpeed  + getAcceleration()

13.if表達式:println(if(x>10)"greater"else"smaller")

                     val greeting =if(hour<18){

                                               "Good day"

                                           }else {

                                            "Good evening"

                                          }

                      val  message = "You are ${ if(age < 18)"young"else "of age"} 

                      println(message)

14.when表達式,相當與if表達式,但是else 是必需的,要覆蓋全部情況

val vehicle = "Car"

when(vehicle){
   "Car" , "Bike" -> print("Vehicle")
    else ->print("Unmatch")
}
//逗號分開兩種不同的情況,


//when還可以判斷變量類型
val vehicle = "Car"

when(vehicle){
   is String->
   is User->
}

//檢驗特定值範圍
val risk = when(risks){
    in 1..20 ->"small risk"
    !in 21..40->"minor risk"
    !in 41..60 ->major risk"
    else->"undefined risk"
}
println(risk)

/* 重要一點如果條件包含所有,可以不加else ,編譯器會幫你解決問題*/

15.Kotlin循環 for ( item in array){

                              print(item)

                         }

可以根據索引,withIndex庫方法,可返回IndexedValue屬性列表,其中包含一個索引和一個數值

for(  (index,value) in array.withIndex() ){

    println("Element at $index is $value")

}

其他如while break continue do...while 與java類似

break 語句提供標註形式

val charRange = 'A'..'B'
val intRange = 1..6
outer@ for(value in intRange){
   println("Outer loop : $value ")
   
   for(char in charRange){
          if(char == 'B')
                break@outer
              
            println("$char")
     {
 }
//prints 
Outer loop: 1
A
break@outer 跳到標記循環之後的語句

16.異常處理          Kotlin中全部異常均爲非檢查型

fun foo(){
   throw IOException()
}



fun bar(){
   foo()//no need to try-catch block
}



/* Kotlin try表達式定義爲表達式,可以返回值*/
//Android 檢驗是否成功安裝
val result = try {
  context.packageManager.getPackageInfo("com.text.app",0)
}catch(ex: PackageManager.NameNotFoundException{
  false
}

Kotlin try表達式定義爲表達式,可以返回值

17. val只有只讀性質,在大多數時候可將其視做常量,初始化過程可能延遲

const val MAX_LOG_ENTRIES = 100
     @MyLogger(MAX_LOG_ENTRIES)
    // value availiable at compile time
     class Test{}
//保證在編譯期已知,用const關鍵字

三、函數

1.定義函數

fun main(args: Array<String>){
        println("Hello,World!")
}
fun double(i : Int): Int{
        return 2*i
}

2.返回函數的形式

fun printSum(a:Int,b:Int): Unit{//不返回值
    val sum = a+b
    print(sum)
}
fun printSum(a:Int,b:Int): Int{//返回Int
   return sum
}

3.vararg參數

可以傳任意數量的參數,正常狀態下,期待爲加載特定類型的泛型數組

fun print Sum(vararg numbers: Int){
         val sum = numbers.sum()
         print(sum)
}
printSum(1,2,3,4,5)//Prints:15
printSum()//Prints:0
fun printAll(vararg texts: Any){
        val allTexts = texts.joinToString(",")
        println(allTexts)
}
//Usage
printAll("A",1,,'c')//Prints: A,1,c

4.單表達函數

fun square(x:Int):Int = x*x
//在安卓項目中根據佈局
class AddressAdapter : ItemAdapter<AddressAdapter.ViewHolder>(){
    override fun getLayoutId() = R.layout.choose_address_view
    override fun onCreateViewHolder(itemView : View)
    ViewHolder(itemView)
}
//獨立對象上的鏈接多項操作
fun textFormatted(text: String,name: String) = text
                 .trim()
                 .capitalize()
                 .replace("{name}", name)
val formatted = textFormated("hello,{name}","Marcin")
println(formatted)
             

5.命令式編程和聲明式編程:  命令式編程範例描述了所需的實際步驟,進而執行某項操作

                                                聲明式編程範例描述了期望結果,但無須按照步驟予以實現(行爲實現),程序通過表達式或聲明

                                        來實現

6.尾遞歸函數:

tailrec fun getState(state: State, n:Int):State = 
        if(n<=0) state
        else getState(state.nextState(),n-1)

尾遞歸函數無需擔心StackOverflowError,可通過編譯器優化遞歸調用

//尾遞歸工作方式
public static final State getState(@NotNull State state, int n)
{
      while(true){
                if(n<=0)return state;
                state = state.nextState();
                n=n-1;
               }
}

7.默認參數值

fun printValue(value: String,prefix:String="",suffix:String=""){
        print(prefix)
        print(value)
        println(suffix)
}
printValue("str")//Prints: str
printValue("str","(",")")//Prints: (str)

8.命名參數語法

對於Kotlin參數,命名參數語法還具有額外的特徵,當改變某個參數名時,也許會由於該名稱會用於其他項目中,因而將會產生錯誤。使用命名參數語法,Kotlin庫生成器一般會對此謹慎處理

9.頂級函數

//Printer.kt
fun PrintTwo(){
    print(2)
}

//將代碼編譯爲Java字節碼
public final calss PrintKt{
           public static void printTwo(){
                     System.out.print(2)
           }
}

10.頂級函數的底層機制

@file:JvmName("Printer")

相當與java引入Printer.java文件

@file:JvmName("Math")引用數學幫助函數 

用修改生成類名的JvmName註解十分有用,有助於解決命名衝突問題

11.局部函數

fun makeStudentList() : List<Student>{
   var students: List<Student> = emptyList()
   fun addStudent(name:String,state:Student.State = 
                  Student.State.New){
             students +=Student(name,state,courses = emptyList())
    }
  //...
  addStudent("Ada")
  addStudent("Donald")
 //...
 return students
}

12.無返回類型

函數可簡化錯誤拋出機制,如throwError

fun fail () :Nothing = throw Error()

簡化單元測試中的錯誤機制

Nothing是所有類型的子類型,即可空類型和非空類型,同時這也是Nothing被稱作空類型的原因,意味着不存在任何值在運行期內包含該類型,無法形成Nothing實例,僅存在從函數返回的錯誤信息,將其作爲返回類型。對於Nothing來說,沒有必要添加任何內容以對該類型產生影響

 四、類和對象

1.定義類

在Kotlin中是用class關鍵字定義的 ex. class Person

                                                            val person = Person()

在Kotlin文件中無需使用new關鍵字,在Java文件中使用new 關鍵字

2.屬性

Kotlin用constructor方法相當於Java類的構造方法,替代方法是可以用init代替constructor

//1
class Person{
      var name: String
      var age:Int
       
      constructor(name:String, age:Int){
            this.name = name
            this.age  = age
        }
}



//2
class Person constructor(name:String, age:Int){
      var name: String
      var age:Int
       
      init{
            this.name = name
            this.age  = age
        }
}

3.讀-寫形式 和 只讀屬性

用val 關鍵字 僅生成 getter方法

Kotlin不支持只寫屬性

4.屬性訪問語法

Car car = new Car(7.4)

car.setSpeed(9.2)

Double speed = car .getSpeed

5.自定義getter/setter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章