一天入門Kotlin學習筆記(一)-數據類型

前言

本系列文章作爲學習簡單的學習筆記,其目的在於2個:

  • 記錄自己學過的知識
  • 本着分享交流的原則分享

本系列適合完全沒有學過Kotlin並且像快速入門的同學,本人現在也是在學習中,所以作爲筆記難免會有錯誤,如果我理解的不對或是有疑問,真誠希望可以在留言區大家進行討論。

推薦學習資料

數據類型

1. Boolean類型
val b:Boolean=true

定義類型格式 :訪問修飾符 修飾符 對象名:類名=具體賦值

變量的修飾符有2種:

  • val 不可變的屬性聲明
  • var 可變屬性聲明

val修飾類似於java中的final修飾,定義時必須初始化(或在構造方法中或是init{}方法中),但是不完全相同Kotlin常量用const修飾。注意是不可變屬性不是靜態屬性

var是可變屬性,可以不初始化,可以多次賦值

在kotlin中不像java,基本數據類型可以用小寫的boolean聲明。這裏必須用他的裝箱類來定義。
訪問修飾符默認是public(java是defualt)

2. Number類型
val l:Long=1231231L
val l1:Long=1231231
val l2:Long=1231231l//error
val f:Float=3f
val f1:Float=3.0F
val f2:Float=3.0//error
val d1:Double=3.0
val s:Short=12712
val byte:Byte=127

在java中有基本數據類型int對應的裝箱類型Integer,Kotlin中是沒有這個概念的Kotlin中的Int相當於int與Integer合體,編譯器會幫我選擇。
Kotlin中不存在隱式轉換,如:

        short s = 0;
        int i = 0;
        long l = 0;
        i = s;
        l = i;
        l = s;

java中正確 Kotlin中

    val s: Short = 0
    var i: Int = 0
    i = s.toInt()
    i = s//error
3. Char類型

與java基本一致,這裏列出一些常用的轉義字符

轉義字符 含義
\t 製表符
\b 光標後退一個字符
\n 回車
\r 光標回到行首
單引號
" 雙引號
\ 反斜槓
$ 美元符號,Kotlin 支持美元符號開頭的字符模板
4. String類型
  • == 與 ===
val str: String = "str"
val str1: String = String(charArrayOf('s', 't', 'r'))

fun main(args: Array<String>) {
    println(str== str1)
    println(str=== str1)

}

結果: 
true  
false

Kotlin中== 相當於.equals()對象比較相等用 ===

  • 字符串模板
    val int1: Int = 1
    val int2: Int = 2

    println(" " + int1+ " + " + int2 + " = " + (int1 + int2))
    println("$int1 + $int2 = ${int1 + int2}")

    //hello "world"
    //前面提到的轉義字符
    println("hello \"world\"")
    val s:String="""

        \t
        \n
        hello World
    """
    println(s)
    
    
    
結果:  
1 + 2 = 3
1 + 2 = 3
hello "world"


        \t
        \n
        hello World
    
"${}"字符串模板 """ """ 原始字符串  
5. 類與對象

直接將理論還是不夠直觀,所以直接上代碼:

class 美女 private constructor(val 性格: String, val 長相: String, val 聲音: String) {//1
    constructor(性格: String, 長相: String, 聲音: String, 三圍: String) : this(性格, 長相, 聲音)//2 
    constructor(性格: String, 長相: String) : this(性格, 長相, "動聽")
}

class 帥哥(性格: String, 長相: String, 聲音: String) : 人(性格, 長相, 聲音) {//3
    init {//4
        println("帥哥: 性格:$性格,長相:$長相,聲音:$聲音")

    }


}

class Test{//5
    val d: Double
    val i: Int

    constructor(double: Double, int: Int) {
        d = double
        i = int
    }

    constructor(double: Double) {
        d = double
        i = 0
    }

}

open class 人(val 性格: String, val 長相: String, val 聲音: String) {
    init {
        println("new 了一個${this.javaClass.simpleName}: 性格:$性格,長相:$長相,聲音:$聲音")

    }

    fun funA() {
        println(this.聲音)//6
    }
}

fun main(args: Array<String>) {
    val 我喜歡的妹子: 美女 = 美女("溫柔", "甜美", "動聽","三圍")
    val 我膜拜的漢子: 帥哥 = 帥哥("彪悍", "帥氣", "渾厚")
    val test1 = Test(2.0)
    val test2 = Test(2.0, 3)
}

這段代碼有點長,但是內容非常簡單,我也會分開來說

  1. 類的定義:
class <類名> 構造器(實參1/形參1,實參2/形參2){
    
}

Kotlin的構造函數分爲主構造器(primary constructor)和次級構造器(secondary constructor)。
簡單理解就是寫在類名後面的爲主構造器
寫在類裏面的爲次構造器
當主構造器被可見性修飾符修飾時,必須加上constructor關鍵字否則可以省略,如3處帥哥類

  1. 只有被open關鍵字修飾的類才能被繼承
  • Kotlin中繼承是用冒號:來作爲繼承類或是實現接口
  • 2處爲次構造器,如果定義了主構造器那麼次構造器需要繼承主構造器
  1. 形參和實參 人這個類中定義的形參,帥哥定義的實參
  2. init方法
    當使用主構造器時,由於沒有方法體,那麼一些初始化的操作可以在init{}方法中實現。這個方法每次創建對象都會被執行
  3. 只有次構造器那麼構造方法可以重載
  4. 形參可以在方法中調用(如果val 聲音: String去掉val這行會報錯)
  5. java中所有類的父類是Object,Kotlin中所有類的父類是Any

更多知識參考Kotlin的構造函數

6. 空類型

在Kotlin對函數有更嚴格的要求,如在Java中你可以寫這樣一個方法:

public String getName() {
        return null;
    }

這樣完全是沒問題的,但是在Kotlin中卻不可以
圖片.png
會提示錯誤,意思說你不能返回一個空字符串
PS: 這裏簡單說下Kotlin中方法的定義:

<可見性修飾符> <其他修飾符> fun 方法名(形參1,形參2):<返回值類型>{
    
} 

這個不難理解,基本和Java一樣都是固定格式,沒什麼好說的.
如果這個方法返回本省就可能爲空怎麼辦呢?可以這樣寫:

fun getName(): String? {
    return null
}

String?表示他是一個可null的字符串,我們調用時可以這樣:

fun getName(): String? {
    return null
}

fun main(args: Array<String>) {

    val nameB:String? = getName()
    println(nameB?.length)//  
}

nameB?這樣表示name不爲空那麼就輸出長度,否則打印null,這樣程序不會崩潰
但是還有一種情況如下:

    val value:String ?= "HelloWorld"
    println(value!!.length)

定義value是可空類型,但是我明確知道它不是null,那麼我們可以使用value!!,表示我已經確定知道這個值不是null,不要給我報編譯錯誤。

總結

  • val notNull: String = null //錯誤,不能爲空
  • val nullable: String? = null //正確,可以爲空
  • notNull.length //正確,不爲空的值可以直接使用
  • nullable.length //錯誤,可能爲空,不能直接獲取長度
  • nullable!!.length //正確,強制認定nullable不可空
  • nullalbe?.length //正確,若nullable爲空,返回空
7. 智能類型轉換

下面來看:

 if (name != null)
        println(name.length) 
    else 
        return
        
等價於:

  val name: String = getName()?: return
  println(name.length) 

通過條件語句確定name一定不爲空那麼可以直接調用方法,這就是隻能轉換String?轉String

Java中:

class Parent{
    
}
class Chlid extends Parent{
    public int age=11
}

public void main(){
    Parent parent=new Child()
    ((Chlid)parent).age
}

只有強轉才能調用子類的方法,但是在Kotlin中卻不用 如下:

val parentA: Parent = Chlid()
    if (parentA is Chlid) {
        parentA.age
    }

is關鍵字,常用語判斷,如果判斷成立那麼parentA就是Child不用強轉
關於強轉如下:

    val chlidA: Chlid = parentB as Chlid//非安全強轉失敗crash
    val chlidB: Chlid? = parentB as? Chlid//安全強轉失敗爲null

總結:

◆ Java Style類型轉換

  • val sub: SubClass = parent as SubClass
  • 類似於Java的類型轉換,失敗則拋異常

◆ 安全類型轉換

  • val sub: SubClass? = parent as? SubClass
  • 如果轉換失敗,返回null ,不拋異常

◆ 智能類型轉換

  • if(parent is SubClass) parent. <子類的成員>
  • 編譯器儘可能的推導類型,遠離無用的類型轉換
  • if(nullable != null) nullable.length
  • 正確!因爲我們確認nullable不爲空!.
8. 區間

關於區間比較簡單 直接說下概念:

  • 個數學上的概念,表示範圍
  • ClosedRange的子類, IntRange最常用
  • 基本寫法:
    • 0…100表示[0, 100]
    • 0 until 100表示[0, 100)
    • i in 0…100判斷i是否在區間[0, 100]中

代碼:

val rangeInt: IntRange = 1..1024//[0,1024]
val range_exclusive: IntRange = 0 until 1024//[0,1024)
val b: Boolean = true

fun main(args: Array<String>) {
    println(rangeInt.contains(50))
    println(rangeInt.contains(1024))
    println(1024 in rangeInt)
    println(range_exclusive.contains(1024))
    println(1024 in range_exclusive)

    for (i in range_exclusive) {
        println(i)
    }
}
9. 數組

數組的使用方法

  • val array: Array = array0f…)

基本操作

  • print array[i] 輸出第i個成員
  • array[i] = ,“Hello” 給第i個成員賦值
  • array.length 數組的長度

爲了避免不必要的裝箱和拆箱, 基本類型的數組是定製的如下:
圖片.png
例子:

val arrayInt: IntArray = intArrayOf(1, 3, 5, 7)
val arrayChar: CharArray = charArrayOf('H', 'e', 'l', 'l', 'o')
val arrayString: Array<String> = arrayOf("陳", "冠", "希")
val array書記: Array<市委書記> = arrayOf(市委書記("張"), 市委書記("李"), 市委書記("王"))

fun main(args: Array<String>) {
    println(arrayInt.size)
    for (i in arrayInt) {
        println(i)
    }

    println(arrayChar.joinToString(""))//連接字符
    println(arrayString.joinToString(""))//連接字符串
    println(array書記[1])
    array書記[1] = 市委書記("趙")
    println(array書記[1])
    println(arrayInt.slice(1..3))//表示的是下標 slice表示"切片"
}

結語

本篇就到這裏下一篇將說下程序結構相關。

Github源碼直接運行,包含全部詳細筆記

發佈了33 篇原創文章 · 獲贊 8 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章