1. 程式人生 > >Kotlin詳解:第一章,基本語法

Kotlin詳解:第一章,基本語法

一,簡介

  • Kotlin是JetBrains開發的基於JVM的語言,Kotlin可以編譯成Java位元組碼,也可以編譯成JavaScript,方便在沒有JVM的裝置上執行。
  • 特點:比Java更安全,能夠靜態檢測常見的陷阱。如:引用空指標。程式碼更易表現,書寫方便,便於閱讀。支援函數語言程式設計,如:使用lambda表示式來更方便地解決問題。
  • Kotlin是一種現代化的語言,語法彙集了很多語言的優點,是未來程式設計的一種趨勢。

二,開發環境

三,資料型別

(1),開始編寫第一段程式碼,這裡使用IntelliJ IDEA來講解,建立一個Kotlin檔案,Kotlin是以kt為字尾
這裡寫圖片描述
然後寫一個mian方法列印一句話
這裡寫圖片描述
(2),基本資料型別

①,資料型別和Java一樣也有integer,float,boolean,不同的是Kotlin都是以物件的形式出現的。

    val i: Int = 1 
    val f: Float = 1f
    val d: Double = 1.0 
    val l: Long = 1  
    val sh: Short = 1 
    val b: Boolean = true
    val s: String = "Hello Word"

    val i = 1 
    val f = 1f
    val d = 1.0 
    val l = 1  
    val sh = 1 
    val b = true
    val s = "Hello Word"

val代表常量,命名規則 :變數名+冒號+資料型別。上邊程式碼效果是一樣的,這裡資料型別可以不寫,編譯器會自動識別。程式碼後邊的分號也不是必須的。

②,在Java中可以隱式轉換,一個int型別是可以直接賦值給double型別的。而Kotlin不能隱式轉換,需要強轉。

//Kotlin程式碼
val i: Int = 8
val d: Double = i.toDouble()

//Java程式碼
int i=8;
double d=i;

③,String可以像陣列一樣被訪問,也可以迭代。

    val s = "Hello Word"
    val c = s[2]
    for(c in s){
        println(c)
    }

④,這裡‘’==‘’和Java中的‘’equals‘’是等價的。‘’===‘’和Java中的‘’==‘’是等價的

    val s: String = "Hello Word"
    val s1: String = String(charArrayOf('H', 'e', 'l', 'l','o', ' ', 'W', 'o', 'r', 'd'))
    println(s == s1) //列印結果 true
    println(s === s1)//列印結果 false

⑤,在Kotlin中引入了字串模板,用“$”表示

    val num1 = 3
    val num2 = 4
    println("" + num1 + "+" + num2 + "=" + (num1 + num2))//java方式
    println("$num1+$num2=${num1 + num2}")//Kotlin方式

⑥,空型別安全
在Java中定義一個變數,呼叫變數時通常會進行空值判斷,否則會有空指標的異常。而在Kotlin程式會對空型別進行檢測,則不會出現空指標異常。如果想讓變數為空,需要在變數後邊加上?


    var name: String = null //這裡編譯器是不會通過的,不能是null
    var sex: String? = null // 這樣是沒問題的

    println(sex.length) //這樣是不行的,編譯不通過
    println(sex?.length) //這樣沒問題
    println(sex!!.length) // 注意操作符!!,只有在sex不為空的情況下才能使用,否則會拋異常

在集合中可以使用filterNotNull過濾掉null型別的資料

    val list : List<String?> = listOf(
            "red",
            "orange",
            "yellow",
            "gree",
            "blue",
            null
    )
    //過濾掉null
    val colors:List<String> = list.filterNotNull()

⑦,在Java中有基本型別和裝箱型別,如:int基本型別,Integer裝箱型別。Kotlin中不用關心這些,編譯器會自動選擇。

(3),變數

  • 在Kotlin中, 一切都是物件。所以,所有變數也都是物件(也就是說,任何變數都是根據引用型別來使用的)
  • Kotlin的變數分為 var (可變的) 和 val (不可變的)。
  • 儘量在Kotlin中首選使用val不變值,這樣做的好處是可預測的行為和執行緒安全。

(4),包(package)
在Kotlin中也沿襲了Java的 package 這個概念,同時做了一些擴充套件。我們可以在一個包中引用另一個包

這裡寫圖片描述
在student包中引用了teacher包,這裡是可以編譯通過的,呼叫Mark類的時候引用的也是teacher。可以看出Kotlin中我們可以修改包的引用,但是為了專案結構更加清晰一般我們不會這麼做。

這裡寫圖片描述

如果一個類類名比較長,呼叫時還可以起個別名。這裡呼叫Mark類時,給Mark類起名為a,直接用a呼叫此類。

(5),區間
區間就是數學中的概念,開區間和閉區間。比如宣告一個0到100的區間,區間也可以迭代。

 val intR:IntRange=0..100   //閉區間  [0,100]
 val  intR1:IntRange=0 until 100 // 前閉後開  [0,100)=[1,99]
 //迴圈輸出區間中的值
 for(i in intR){
     println(i)
 }

(6),陣列
陣列和Java中的一樣,我們看下如何定義陣列

//定義陣列
val array:IntArray= intArrayOf(1,2,3,4,5)
val charArray:CharArray = charArrayOf('H','e','l','l','0')
val stringArray:Array<String> = arrayOf("你是","我的","眼")

println(array.size)   // 陣列的長度
stringArray[1]="他"  //修改陣列的值
println(array.slice(2..3))  //陣列的擷取
//陣列遍歷
for(i in array){
   println(i)
}

(7),for迴圈
for 迴圈可以對任何提供迭代器(iterator)的物件進行遍歷

fun main(args: Array<String>): Unit {
    //方式一
    for (arg in args) {
        println(arg)
    }
    //方式二
    for ((index, value) in args.withIndex()) {
        println("$index -> $value")
    }
    //方式三
    for (arg in args.withIndex()) {
        println("${arg.index} -> ${arg.value}")
    }
}

四,類和函式

(1),如何定義一個類,類的屬性
①,類

class Student(name: String, sex: String, age: String)

定義類用class關鍵字,如果類中沒有其他內容,可以省去大括號,並且這個類有一個預設的構造器

class Student(name: String, sex: String, age: String){
    init {
        //預設構造器函式
        println("學生:$name 性別 $sex 年齡 $age")
    }
}
//呼叫這個類
val s:Student= Student("張三","男","20")

init就是這個類預設的建構函式,類的呼叫不再需要new關鍵字。
②,屬性

Java程式碼中定義一個屬性,需要寫它的set和get方法。Kotlin中預設有set和get方法

//Java程式碼
public class Student {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    } 
}
...
Student student=new Student();
student.setName("小明");
String name=student.getName();

//Kotlin程式碼

 class Student {
     var name: String = ""
 }
 ...
 val student=Student()
 student.name="小明"
 val name=student.name

我們也可以修改預設的方法,如果我們需要在set和get中訪問自身的值,可以通過field這個預留欄位來訪問。

class Student {
    var name: String = ""
    get() = field.toUpperCase()
    set(value) {
        field="name=$name"
    }
}

(2),類的繼承

class Student(name: String, sex: String, age: String):Course(name)
open class Course(name:String)
  • 學生類繼承課程類,繼承這裡用 “:” 表示。我們可以發現用冒號的地方真多,變數的宣告,類的繼承,函式的返回值型別,都用到了 “:”進行表示。
  • 預設任何類都是繼承Any,這裡和Java中的(Object)類似。
  • 所有類預設是不可繼承的,如果想繼承需要用open或abstract關鍵字。
  • 當我們只有一個構造器時,需要從父類繼承下來的構造器中指定需要的引數,這裡用作替換Java中的super

(3),函式

①,這是一個main函式,函式可以用fun關鍵字來定義。

fun main(args: Array<String>) {
   println("Hello word")
}

這個函式沒有返回值,如果沒有指定函式的返回值,它返回就是Unit,和Java中的void類似。但是Unit也是一個物件。

②,我們也可以指定函式的返回值,這幾種寫法是一樣的。如果返回的只是一個結果,那麼可以省略大括號,直接等於返回值。也可以直接省略返回值型別。

//寫法1
fun add(a: Int, b: Int): Int {
    return a + b
}

//寫法2
fun add (a:Int,b:Int):Int=a+b

//寫法3
fun add(a: Int, b: Int) {
    return a + b
}

//寫法4
fun add (a:Int,b:Int)=a+b

④,我們也可以給函式的引數指定預設值,指定預設值的引數可以不傳。注意:如果第一個引數有預設值,其他引數沒有預設值,那麼依然需要傳入引數。與Java中方法的過載很類似的,Kotlin相當於把多個過載方法合併成了一個。

    //Kotlin程式碼
    fun student(name: String, sex: String = "男") {
        println("名字:$name 性別:$sex")
    }
    student("張三")
    student("小紅", "女")

    //Java程式碼
     void student(String name, String sex) {
        System.out.println("name=" + name + ",sex=" + sex);
    }

    void student(String name) {
        System.out.println("name=" + name);
    }

五,表示式

(1),Lamdba表示式
①,Lambda表示式是一個匿名函式,將行為像資料一樣傳遞,表示式使用”->”將引數和主體分開,”->”前面是引數部分,後面這是主體部分。Lambda表示式在Java8中引入的,具體用法這裡不再講解,讀者可以閱讀有關文章。這是一段Java程式碼,使用了Lambda表示式new一個執行緒。

  new Thread(new Runnable() {
             @Override
             public void run() {
                 System.out.println("lambda");
             }
         }).start();

   new Thread( () -> System.out.println("lambda") ).start();
  //這段程式碼可以看出,把一個內部類當成一個引數傳入,程式碼簡化了很多

②,再看下Kotlin程式碼如何使用Lambda表示式。

  //匿名函式
  val add=fun (a: Int, b: Int): Int {
        return a + b
  }
  //Lambda表示式寫法
  val add={a:Int,b:Int->a+b}

  //Lambda表示式,沒有"->"
  val student={
      println("我是學生")
  }

Lambda表示式和匿名函式類似。可以看到”->”前邊是引數,”->”後邊是返回值。當然”->”也不是必須的。就像這個學生函式,不需要引數,不需要返回值。
③,呼叫Lambda表示式,傳入兩個值,輸出2。這裡我們注意到,在呼叫Lambda時用到了小括號。

 println(add(1,1))

(2),分支表示式

在kotlin中if和else 可以是表示式,也可以是程式碼塊

    //常規寫法
    fun max1(a: Int, b: Int): Int {
        var num: Int
        if (a > b) {
            num = a
        } else {
            num = b
        }
        return num
    }

    //程式碼塊寫法,表示式可以是程式碼塊
    fun max(a: Int, b: Int): Int {
        val num = if (a > b) {
            a
        } else {
            b
        }
        return num
    }

注:kotlin中沒有三元表示式true? 1: 0 ,對應的寫法 if(true) 1 else 0
(3),when表示式
when表示式和switch類似,在kotlin中沒有switch,替代它的是when表示式。else就相當於switch中的default

    val x = -1
    when (x) {
        is Int -> print("is Int")
        -1, 0 -> print("x == 0")   // 同時滿足-10的條件,相當於switch中去掉break
        1 -> print("x == 1")
        2 -> print("x == 2")
        else -> {
            print("")  // 不是上述條件  相當於switch中的default
        }
    }

下一篇:kotlin進階