kotlin語言教程,Kotlin 總結

 2023-12-25 阅读 28 评论 0

摘要:文章目錄1、Kotlin 介紹2、知識點總結2.1、變量2.2、函數(普通函數)2.3、內置類型2.4、類型同步2.5、表達式2.6、高階函數3、Kotlin 知識體系4、為什么要學習 Kotlin5、Kotlin 的工作原理6、Kotlin 的優點7、輸出“Hello World” 原創不易,希望能得到一

文章目錄

    • 1、Kotlin 介紹
    • 2、知識點總結
      • 2.1、變量
      • 2.2、函數(普通函數)
      • 2.3、內置類型
      • 2.4、類型同步
      • 2.5、表達式
      • 2.6、高階函數
    • 3、Kotlin 知識體系
    • 4、為什么要學習 Kotlin
    • 5、Kotlin 的工作原理
    • 6、Kotlin 的優點
    • 7、輸出“Hello World”

原創不易,希望能得到一個贊,感謝各位!

1、Kotlin 介紹

一丶Kotlin 是什么?
Kotlin可以編譯成Java字節碼,也可以編譯成JavaScript,方便在沒有JVM的設備上運行。除此之外Kotlin還可以編譯成二進制代碼直接運行在機器上(例如嵌入式設備或 iOS)。

kotlin語言教程?Kotlin已正式成為Android官方支持開發語言。

二丶Kotlin 簡介
2011年7月,JetBrains推出Kotlin項目,這是一個面向JVM的新語言 ,它已被開發一年之久。JetBrains負責人Dmitry Jemerov說,大多數語言沒有他們正在尋找的特性,Scala除外。但是,他指出了Scala的編譯時間慢這一明顯缺陷。Kotlin的既定目標之一是像Java一樣快速編譯。 2012年2月,JetBrains以Apache 2許可證開源此項目。

Jetbrains希望這個新語言能夠推動IntelliJ IDEA的銷售。

Kotlin v1.0于2016年2月15日發布。這被認為是第一個官方穩定版本,并且JetBrains已準備從該版本開始的長期向后兼容性。

在Google I/O 2017中,Google宣布在Android上為Kotlin提供一等支持。

kotlin遍歷數組?三丶為什么使用 Kotlin

  1. 簡介(數據類擴展方法區間)
  2. 空值安全
  3. 100%兼容java scala
  4. 函數式編程 JDK1.8 lambda表達式
  5. 協程(thread)
  6. DSL(領域特定語言)
  7. 簡潔: 大大減少樣板代碼的數量
  8. 安全: 避免空指針異常等整個類的錯誤
  9. 互操作性: 充分利用 JVM、Android 和瀏覽器的現有庫
  10. 工具友好: 可用任何 Java IDE 或者使用命令行構建

四丶Kotlin 的發展

  • Android 第一開發語言
  • Springboot2.0第一開發語言

五丶Kotlin 的前景

  1. Kotlin script(gradle).kts
  2. Java虛擬機應用
    Web kotlinee
    javafx
  3. 前端開發 kotlinjs
  4. Android開發
  5. 支持開發ios
  6. kotlin Native程序(完全拋棄JVM虛擬機)
    全棧工程師

六丶Kotlin 應用場景
Web前端
Web后端
Android移動端
Server腳本
桌面游戲

七丶打印“Hello World”

fun main() {println("Hello World")
}

kotlin性能、八丶學習資料

官方文檔
Kotlin源碼
Kotlin官方博客

2、知識點總結

2.1、變量

Kotlin 變量
9/100
發布文章
qq_27494201
未選擇任何文件

1丶語法規則、類型推導機制

Kotlin 支持類型推導機制,所以使用 val、var來聲明變量

  • 關鍵字:val
    意思:聲明一個不可變的變量
val age = 21;		
  • 關鍵字:var
    意思:聲明一個可變的變量
var name = "wangrui"

kotlin入門、🔺Kotlin 雖然擁有類型推導機制,但是并不能滿足延遲賦值的場景,如下:

在這里插入圖片描述
所以,就誕生了顯式聲明變量類型這個東西

在這里插入圖片描述
Kotlin 完全拋棄了 Java 中的基本數據類型,全部使用了對象數據類型。在 Java 中 int 是關鍵字,而在 Kotlin 中 Int 變成了一個類,它擁有自己的方法和繼承結構。
如圖: Java 和 Kotlin 數據類型對照表

在這里插入圖片描述

學到這里,小伙伴們一定會有疑問

kotlin優點,2丶為什么要有 val 和 var 這樣的設定

  • (1)為了解決 Java 中 final 關鍵字沒有被合理使用的問題。
  • (2)當項目越來越復雜,參與開發的人越來越多時,你永遠不知道一個可變的變量會在什么時候被誰修改了,即使它原本不應該被修改,這就經常會導致出現一些很難排查的問題

3丶什么時候用 val,什么時候用var呢?
永遠優先使用 val 來聲明一個變量,而當 val 沒有辦法滿足你的需求時再使用 var。這樣設計出來的程序會更加健壯,也更加符合高質量的編程規范

2.2、函數(普通函數)

1丶課前須知
大家閱讀之前,要養成把方法理解為函數習慣。在Kotlin中 主要強調函數,所以我們只要把方法理解為函數即可。其次Kotlin 真的把函數玩的特別強大,希望大家好好學習本節內容!

2丶語法規則

  • 關鍵字:fun
    在這里插入圖片描述

3丶利用函數求兩個數之間的最大值

fun main(){val num1 = 10;val num2 = 20;println(getMax(num1,num2))
}fun getMax(num1:Int,num2:Int): Int{return max(num1,num2)
}

kotlin特性,運行結果
在這里插入圖片描述
代碼分析:
上面的代碼沒什么難度,max() 函數是Kotlin 中的內置函數,返回的是兩個參數里最大的數。

4丶Kotlin 語法糖
概念(很好理解,請用心閱讀):當一個函數中只有一行代碼時,Kotlin 允許我們不必編寫函數體,可以直接將唯一的一行代碼寫在函數定義的尾部,中間用等號連接即可。

fun getMax(num1: Int,num2: Int): Int = max(num1,num2)

代碼分析:
利用:語法糖‘{ }’ 大括號去掉了,同時 return 也去掉了。

你以為這樣就夠簡介了嗎?不,往下看

fun getMax(num1: Int,num2: Int) = max(num1,num2)

代碼分析:
利用:語法糖 + 類型推導機制,前面我們講 Kotlin 變量 的時候,引入了這個概念,在賦值的時候 Kotlin 會智能推導出右邊的類型。這樣講是不是瞬間就明白了上面的這行代碼簡化,所以我們這里可以直接省略掉返回值類型

kotlin數組。5丶總結

好啦,那么 函數(也叫:普通函數) 的基礎知識我們就先講到這里。后面還會有 標準函數靜態函數擴展函數這些都是屬于 Kotlin 的高階函數,學習要一步一步慢慢來,把這篇的文章好好理解一下,代碼好好敲一下再繼續學下去!

《上一章》:Kotlin 變量
《下一章》:虛位以待,正在努力編寫中!

2.3、內置類型

一丶基本類型

  • 聲明變量
  • 聲明變量(類型自動推導)
  • 易混淆的 Long 類型標記
  • Kotlin 的數值轉換
  • Kotlin 的字符串

聲明變量
在這里插入圖片描述
聲明變量(類型自動推導)
在這里插入圖片描述
易混淆的 Long 類型標記
在這里插入圖片描述
Kotlin 的數值轉換
在這里插入圖片描述
Kotlin 的字符串
在這里插入圖片描述

kotlin關鍵字、總結

在這里插入圖片描述
二丶數組

  • 區別
  • 數組的創建
  • 數組的長度
  • 數組的讀寫
  • 數組的遍歷寫法一
  • 數組的遍歷寫法二
  • 數組的包含關系

區別:
在這里插入圖片描述
數組的創建:
在這里插入圖片描述
數組的長度
在這里插入圖片描述
數組的讀寫:
在這里插入圖片描述
數組的遍歷寫法一:
在這里插入圖片描述
數組的遍歷寫法二:
在這里插入圖片描述
數組的包含關系:
在這里插入圖片描述

package com.wangrui.kotlinfun main(){// 方式一:創建一個可變長度的整型數組val c0 = intArrayOf(1,2,3,4,5)// 方式二:創建整型數組并且按照每個下標(0~4)依次+1 賦值給數組 c1val c1 = IntArray(5){it + 1}// contentToString() — 將內容轉換成字符串格式println(c1.contentToString());val c0 = intArrayOf(1,2,3,4,5);// 創建整型數組并且按照每個下標(0~4)依次(坐標+1)*3 賦值給數組c1val c1 = IntArray(5){(it + 1)*3}println(c0.contentToString());println(c1.contentToString());val a = IntArray(5)// 得到集合長度println(a.size)val d = arrayOf("Hello","World")d[1] = "Kotlin"println("${d[0]},${d[1]}")val e = floatArrayOf(1f,2f,3f,4f,5f)// in—遍歷for (a in e){println(a)}// array.foreach()    高階函數遍歷//遍歷集合e,并將每次循環得到的每個值賦給a,然后打印ae.forEach { a -> println(a) }
}

在這里插入圖片描述
三丶區間

  • 區間的創建
  • 開區間
  • 倒序區間
  • 區間的迭代
  • 區間的包含關系
  • 區間的應用寫法一
  • 區間的應用寫法二

區間的創建
在這里插入圖片描述
開區間
在這里插入圖片描述
倒序區間
在這里插入圖片描述
區間的迭代
在這里插入圖片描述
區間的包含關系
在這里插入圖片描述
區間的應用寫法一:
在這里插入圖片描述
區間的應用寫法二:
在這里插入圖片描述

package com.wangrui.kotlinfun main(){// in—包含if (1f in e){println("包含")}if (20f !in e){println("不包含")}//區間(正序)val intRange = 1..10val charRange = 'a'..'z'val longRange = 1L..100Lval floatRange = 1f..2fval doubRange = 1.0..2.0// joinToString() — 加入并轉成字符串,join — 加入println(intRange.joinToString())// toString() — 轉成字符串println(floatRange.toString())// 止步——stepval intRangeWitStep = 1..10 step 2val charRangeWithStep = 'a'..'z' step 2val longRanWitStep = 1L..100L step 5println(longRanWitStep.joinToString())// 倒序區間val intRangeReverse = 10 downTo 1val charRangeReverse = 'z' downTo 'a'val longRangeReverse = 100L downTo 1Lprintln(longRangeReverse.joinToString())val array = intArrayOf(1,3,5,7)//遍歷方式1// until — 直到,所以是 0 到 數組.sizefor (i in (0 until array.size)){println(array[i])}//遍歷方式2// indices — 索引,所以 array[i] = 對應元素for (i in array.indices){println(array[i])}}

在這里插入圖片描述
四丶集合框架

  • 簡介
  • 集合框架的接口類型對比
  • 集合框架的創建【List】
  • 集合框架的創建【Map】
  • 集合實現類服用與類型別名
  • 集合框架的讀寫
  • 集合框架的修改
  • 集合框架的讀寫2
  • 集合框架的讀寫3
  • Pair
  • Triple
  • 思考題

簡介
在這里插入圖片描述
集合框架的接口類型對比
在這里插入圖片描述
集合框架的創建【List】
在這里插入圖片描述
集合框架的創建【Map】
在這里插入圖片描述
集合實現類服用與類型別名
在這里插入圖片描述
集合框架的讀寫
在這里插入圖片描述
集合框架的修改
在這里插入圖片描述
集合框架的讀寫2
在這里插入圖片描述
集合框架的讀寫3
在這里插入圖片描述
Pair
在這里插入圖片描述
Triple
在這里插入圖片描述
思考題
在這里插入圖片描述

package com.wangrui.kotlinfun main(){//  創建List集合的方式一:不能添加元素或者刪除元素val intList: List<Int> = listOf(1,2,3)//  創建List集合的方式二:可以添加元素或者刪除元素val intList2: MutableList<Int> = mutableListOf(1,2,3)//  創建Map集合的方式一:不能添加元素或者刪除元素//  Any等價于Java中的 Object//  to 可以理解為:Key to Valueval map:Map<String,Any> = mapOf("name" to "benny","age" to 20)//  創建Map集合的方式二:可以添加元素或者刪除元素val map2:Map<String,Any> = mutableMapOf("name" to "benny","age" to 20)val stringList:MutableList<String> = mutableListOf("98","99","100","num:1","num:2")//  對集合添加元素、刪除元素for (i in 0..10){//      添加元素
//        stringList += "num:$i" // 等價于  stringList.add("num:$i")//結果為:[98, 99, 100, num:1, num:2, num:0, num:1, num:2, num:3, num:4, num:5, num:6, num:7, num:8, num:9, num:10]//      刪除元素stringList -= "num:$i" // 等價于  stringList.remove("num:$i")//當上面代碼注釋后,結果為:[98, 99, 100]}println(stringList)//  Map集合賦值stringList[5] = "HelloWorld"    //等價于 stringList.set(5,"HelloWorld")val valueAt5 = stringList[5]    //  等價于 String valueAt5 = stringList.get(5)val map = HashMap<String,Int>()map["Hello"] = 10//  '[]' 內的值實際上就是Keyprintln(map["Hello"])//  解構:val (x,y) = pairval pair = "Hello" to "Kotlin"val pair2 = Pair("Hello","Kotlin")val first = pair.firstval second = pair.secondprintln(first)println(second)//  解構:val (x,y,z) = tripleval triple = Triple("x",2,3.0)val first = triple.firstval second = triple.secondval third = triple.thirdprintln(first)println(second)println(third)// 作業:// 一、集合該如何遍歷val intNumber: List<Int> = listOf(1,2,3,4,5,6)intNumber.forEach{a -> println(a)}//二、集合的包含關系如何判斷?val intNumber2: List<Int> = listOf(1,2,3,4,5,6)if (4 in intNumber2){println("4包含于集合intNumber2")}if (400 !in intNumber2){println("400不包含于集合intNumber2")}//三丶Scala 選擇自己全新構建了一套集合框架,為什么 Kotlin沒有?}

在這里插入圖片描述
五丶函數

  • 函數的定義
  • 函數的類型
  • 函數的引用
  • 變長參數 【Java】與 【Kotlin】版
  • 多返回值
  • 默認參數
  • 默認參數 — 錯誤實例【X】
  • 解決辦法【√】— 通過:具名參數

1、函數的定義
在這里插入圖片描述

2、函數的類型
在這里插入圖片描述
3、函數的引用
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

4、變長參數
【Java】
在這里插入圖片描述
【Kotlin】
在這里插入圖片描述
多返回值
在這里插入圖片描述
默認參數
在這里插入圖片描述
默認參數 — 錯誤實例【X】
在這里插入圖片描述
解決辦法【√】— 通過:具名參數
在這里插入圖片描述

package com.wangrui.kotlin.bennyhuofun main(vararg args: String) {
//    println(args.contentToString())// 這時的x 為函數類型,具體為:(Foo, String, Long)->Anyval x:(Foo, String, Long)->Any = Foo::barval x0: Function3<Foo, String, Long, Any> = Foo::bar//三者等價// (Foo, String, Long)->Any = Foo.(String, Long)->Any = Function3<Foo, String, Long, Any>//    val y: (Foo, String, Long) -> Any = xval y: Foo.(String,Long) -> Any = xval z: Function3<Foo, String, Long, Any> = x//調用yy函數,并傳入x函數類型作為函數參數yy(y)//拿到 fun foo() { } 的引用val f: ()->Unit = ::foo//拿到 fun foo(p0: Int): String { return  "" } 的引用val g: (Int) ->String = ::foo/*** 拿到:class Foo {fun bar(p0: String, p1: Long): Any{println("one:$p0 Long:$p1")return ""}}的引用*/val h: (Foo, String, Long)->Any= Foo::bar// 變長參數multiParameters(1, 2, 3, 4)//利用具名函數,將值準確傳給 y: StringdefaultParameter(y = "Hello")//解構表達式val (a, b, c) = multiReturnValues() //實現 偽多返回值的場景val r = a + bval r1 = a + c}// p:是一個函數類型,這個函數其實就是 Foo::bar
fun yy(p: (Foo, String, Long) -> Any){p(Foo(), "Hello", 3L)   // Foo()指的是:類的引用,調用對應函數,并進行傳參
}class Foo {fun bar(p0: String, p1: Long): Any{println("one:$p0 Long:$p1")return ""}
}fun foo() { }
fun foo(p0: Int): String { return  "" }//利用具名函數,將值準確傳給 y: String
fun defaultParameter(x: Int = 5, y: String, z: Long = 0L){}// 變長參數
fun multiParameters(vararg ints: Int){println(ints.contentToString())
}// 偽多返回值
fun multiReturnValues(): Triple<Int, Long, Double> {return Triple(1, 3L, 4.0)
}

總結
在這里插入圖片描述
六丶案例:四則計算器

package com.wangrui.kotlin/*input: 3 * 4*/fun main(vararg args: String){if (args.size < 3){return showHelp()}//▲暫時不是很理解 to::plusval operators = mapOf("+" to::plus,"-" to::minus,"*" to::times,"/" to::div)val op = args[1]val opFunc = operators[op]?:return showHelp()try {println("Input:${args.joinToString(" ")}")println("Output:${opFunc(args[0].toInt(),args[2].toInt())}")} catch (e: Exception) {println("Invalid Arguments.")showHelp()}
}fun plus(arg0:Int,arg1:Int):Int{return arg0 + arg1
}fun minus(arg0:Int,arg1:Int):Int{return arg0 - arg1
}fun times(arg0:Int,arg1:Int):Int{return arg0 * arg1
}fun div(arg0:Int,arg1:Int):Int{return arg0 / arg1
}fun showHelp(){println("""Simple Calculator:Input: 3 * 4Output:12""".trimIndent())
}

七丶本章小結
在這里插入圖片描述

2.4、類型同步

一丶類型接口

  • 類的定義1
  • 類的定義2
  • 類的定義3,寫法一
  • 類的定義3,寫法二
  • 類的定義3,寫法三
  • 類的定義3,寫法四
  • 類的實例化
  • 接口的定義
  • 接口的實現
  • 抽象類定義
  • 類的繼承
  • 屬性代理【Java】
  • 屬性代理【Kotlin】
  • 屬性引用

類的定義1
在這里插入圖片描述
類的定義2
在這里插入圖片描述
類的定義3,寫法一
在這里插入圖片描述
類的定義3,寫法二
在這里插入圖片描述
類的定義3,寫法三
在這里插入圖片描述
類的定義3,寫法四
在這里插入圖片描述
類的實例化
在這里插入圖片描述
接口的定義
在這里插入圖片描述
接口的實現
在這里插入圖片描述
抽象類定義
在這里插入圖片描述
類的繼承
在這里插入圖片描述
屬性代理【Java】
在這里插入圖片描述
屬性代理【Kotlin】
在這里插入圖片描述
屬性引用
在這里插入圖片描述
AbsClass

abstract class AbsClass {abstract fun absMethod()open fun overridable(){}fun nonOverridable(){}
}

SimpleInf

package com.bennyhuo.kotlin.types.classes.kotlininterface SimpleInf {val simpleProperty: Int // propertyfun simpleMethod()
}

SimpleClass

package com.bennyhuo.kotlin.types.classes.kotlinopen class SimpleClass(var x: Int, val y: String): AbsClass(), SimpleInf {override val simpleProperty: Intget() {return 2}val z : Longget() {return simpleProperty * 2L}override fun absMethod() {}override fun simpleMethod() {}fun y(){}fun zzz(string: String){}final override fun overridable(){}
}class SimpleClass2(x: Int, y: String): SimpleClass(x, y){}

Person

package com.bennyhuo.kotlin.types.classes.kotlinclass Person(age: Int, name: String) {var age: Int = age //propertyget() {return field}set(value) {println("setAge: $value")field = value}var name: String = nameget() {return field // backing field}set(value) {}
}fun main() {val ageRef = Person::ageval person = Person(18, "Bennyhuo")val nameRef = person::nameageRef.set(person, 20)nameRef.set("Andyhuo")
}

在這里插入圖片描述
二丶擴展方法
文件一.kt

package com.wangrui.kotlin.chapter02fun main(){//利用擴展方法檢測郵箱格式是否正確"admin@bennyhuo.com".isEmpty()//擴展方法舉例1//結果:----------Hello----------println("Hello".padding(10,'-'))//擴展方法舉例2//結果:**********println( "*".times(10))}/*擴展方法*/
//  String  ——  receiver
fun String.isEmail():Boolean{...
}/*擴展方法舉例1*/
fun String.padding(count:Int,char:Char = ' '):String{val padding = (1..count).joinToString(""){char.toString()}//${this}   ——  Stringreturn "${padding}${this}${padding}"
}/*擴展方法舉例2*/
fun String.times(count: Int):String{return (1..count).joinToString(""){this+"哈"}
}

文件二.kt

package com.wangrui.kotlin.chapter02/*定義類*/
class PoorGuy{var pocket:Double = 0.0
}/*擴展方法*/
fun PoorGuy.noMoney(){}/*擴展屬性*/
//property = backing field + getter + setter
var PoorGuy.moneyLeft: Doubleget() {return this.pocket}set(value) {pocket = value}//1、Kotlin里接口不能定義狀態
//2、Kotlin里接口只能定義行為
interface Guy{var moneyLeft: Doubleget() {return 0.0}set(value) {}//只能定義默認行為,想set()或者get()是不行的fun noMoney(){println("no money called.")}
}/*擴展方法的類型*/
fun String.times(count: Int): String{}String::times   (String,Int)->String
"*"::times      (Int)->String

在這里插入圖片描述
三丶空類型安全

package com.wangrui.kotlin.chapter03import org.jetbrains.annotations.NotNullfun main(){//'?'表示該類型可空,所以能接收空值var nullable: String? = "Hello"//這時直接寫:會報錯val length = nullable.length//方法一:當 nullable 一定不為空時,'!!'表示將可空類型轉換為不可空類型 【不推薦】// '!!'強制轉換運算符val length = nullable!!.length/*方法二:當 nullable 不知道是否為空時,'?.'表示安全訪問這個值。    【推薦】其次如果這個值為空,就回返回0給他,因為受到'?:'符號的影響,和Java里的三目有點相似但不是記住喔*/// '?.'安全訪問運算符// '?:' elvis運算符 類似 boolean?a :bval length = nullable?.length?:0*//*空類型的繼承關系*///得出結論//1、String?是String的父類(基類)//2、Number是Int的父類(基類)//引出經典理論//里氏替換原則中說,任何基類可以出現的地方,子類一定可以出現var x:String = "Hello"var y:String? = "World"x = y  //Type mismatch  類型不匹配 ×y = x  //OK √var a:Int = 2var b:Number = 10.0a = b //Type mismatch  類型不匹配 ×b = a //OK  √/*平臺類型*/假設Java代碼如下:public class Person{@NotNull    //利用注解 加上將 return null變成return "null"方式防止空指針異常public String getTitle(){return "null";}}val person = Person()val title: String = person.titleval titleLength = tiele?.length //利用安全運算符防止空指針異常String! 表示平臺類型不知道是否為可空類型}

在這里插入圖片描述
四丶智能類型轉換

package com.wangrui.kotlin.chapter04fun main(){/*Kotlin 的類型轉換*/val kotliner: Kotliner = Person("benny",20)if (kotliner is Person){//as 轉換類型為 Personprintln((kotliner as Person).name)}/*智能類型轉換*///注意:當變量為全局變量時,此時不支持智能類型轉換val kotliner: Kotliner = Person("benny",20)if (kotliner is Person){println(kotliner.name)}/*智能類型轉換作用范圍*/var value:String? = nullvalue = "benny"if (value != null){ //這時value 就變成了 String類型println(value.length)   //如果出了這個{}的區域 value的類型又變回了 String?類型}/*類型的安全轉換*/val kotliner: Kotliner = Person("benny",20)if (kotliner is Person){//安全轉換,失敗返回nullprintln((kotliner as? Person)?.name)}//建議//1、盡可能使用 val 來聲明不可變引用,讓程序的含義更加清晰確定//2、盡可能減少函數對外部變量的訪問,也為函數式編程提供基礎//3、必要時創建局部變量指向外部變量,避免因它變化引起程序錯誤}

在這里插入圖片描述
五丶案例:使用Retrofit 發送網絡請求

package com.wangrui.kotlin.chapter05import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path
import java.io.Fileinterface GitHubApi {@GET("/repos/{owner}/{repo}")fun getRepository(@Path("owner") owner: String, @Path("repo") repo: String): Call<Repository>
}fun main() {//拿到API接口實例val gitHubApi = Retrofit.Builder().baseUrl("https://api.github.com").addConverterFactory(GsonConverterFactory.create()).build().create(GitHubApi::class.java)//拿到響應頭val response = gitHubApi.getRepository("JetBrains", "Kotlin").execute()//獲取資料庫val repository = response.body()//判斷是否為空if(repository == null){println("Error! ${response.code()} - ${response.message()}")} else {println(repository.name)println(repository.owner.login)println(repository.stargazers_count)println(repository.forks_count)println(repository.html_url)File("Kotlin.html").writeText("""<!DOCTYPE html><html><head><meta charset="UTF-8"><title>${repository.owner.login} - ${repository.name}</title></head><body><h1><a href='${repository.html_url}'>${repository.owner.login} - ${repository.name}</a></h1><p>${repository.description}</p><p>Stars: ${repository.stargazers_count}</p><p>Forks: ${repository.forks_count}</p></body></html>""".trimIndent())}
}

Repository(Data數據類)

package com.wangrui.kotlin.chapter05/*** Created by wangrui on 2020-05-29*/
data class Repository(var id: Int,var node_id: String,var name: String,var full_name: String,var private: Boolean,var owner: Owner,var html_url: String,var description: String,var fork: Boolean,var url: String,var forks_url: String,var keys_url: String,var collaborators_url: String,var teams_url: String,var hooks_url: String,var issue_events_url: String,var events_url: String,var assignees_url: String,var branches_url: String,var tags_url: String,var blobs_url: String,var git_tags_url: String,var git_refs_url: String,var trees_url: String,var statuses_url: String,var languages_url: String,var stargazers_url: String,var contributors_url: String,var subscribers_url: String,var subscription_url: String,var commits_url: String,var git_commits_url: String,var comments_url: String,var issue_comment_url: String,var contents_url: String,var compare_url: String,var merges_url: String,var archive_url: String,var downloads_url: String,var issues_url: String,var pulls_url: String,var milestones_url: String,var notifications_url: String,var labels_url: String,var releases_url: String,var deployments_url: String,var created_at: String,var updated_at: String,var pushed_at: String,var git_url: String,var ssh_url: String,var clone_url: String,var svn_url: String,var homepage: String,var size: Int,var stargazers_count: Int,var watchers_count: Int,var language: String,var has_issues: Boolean,var has_projects: Boolean,var has_downloads: Boolean,var has_wiki: Boolean,var has_pages: Boolean,var forks_count: Int,var mirror_url: Any,var archived: Boolean,var disabled: Boolean,var open_issues_count: Int,var license: Any,var forks: Int,var open_issues: Int,var watchers: Int,var default_branch: String,var temp_clone_token: Any,var organization: Organization,var network_count: Int,var subscribers_count: Int
) {data class Owner(var login: String,var id: Int,var node_id: String,var avatar_url: String,var gravatar_id: String,var url: String,var html_url: String,var followers_url: String,var following_url: String,var gists_url: String,var starred_url: String,var subscriptions_url: String,var organizations_url: String,var repos_url: String,var events_url: String,var received_events_url: String,var type: String,var site_admin: Boolean)data class Organization(var login: String,var id: Int,var node_id: String,var avatar_url: String,var gravatar_id: String,var url: String,var html_url: String,var followers_url: String,var following_url: String,var gists_url: String,var starred_url: String,var subscriptions_url: String,var organizations_url: String,var repos_url: String,var events_url: String,var received_events_url: String,var type: String,var site_admin: Boolean)
}

運行Kotlin程序生成HTML文件
在這里插入圖片描述
效果圖:
在這里插入圖片描述
在這里插入圖片描述
六丶本章小結
在這里插入圖片描述

2.5、表達式

一丶常量與變量

package com.wangrui.kotlin.chapter01/*常量*/
//1、只能定義在全局范圍
//2、只能修飾基本類型
//3、必須立即用字面量初始化
const val b = 3fun main(){/*變量*/var a = 2a = 3/*只讀變量*/val b:Int/*常量引用*/    //  了解即可//Person(18,"Bennyhuo") 堆上創建對象val person = Person(18,"Bennyhuo")//對象改變但飲用沒變person.age = 19/*編譯期和運行時常量*///編譯時即可確定常量的值,并用只替換掉用處const val b = 3//運行時才能確定值,調用處通過引用獲取值val c:Int}// val作為只讀變量原因舉例:class X{val b:Int//此時每次返回b的值都是不一樣的,random —— 隨機數get() {return (Math.random()*100).toInt()}}

在這里插入圖片描述
二丶分支表達式

package com.wangrui.kotlin.chapter02import java.lang.Exceptionfun main(){/*表達式一:if...else*///1、跟Java語法一樣//2、kotlin里沒有三目表達式/*表達式二:when...*///1、與Java switch 意思一樣//Java語法:switch(a){case 0: c=5;break;case 1: c=100;breakdefault: c=20;}//kotlin語法一:when(a){0 -> c = 51 -> c = 100else -> c = 20}/*    kotlin語法二:*/c = when(a){0 -> 51 -> 100else -> 20}//when...其他用法//表示先接收用戶輸入的值,并且賦給input再進行開關語句c = when(val input = readLine()){null -> 0else ->input.length}/*表達式三:try...catch*///kotlin 寫法一:try {c = a/b}catch (e:Exception){e.printStackTrace()c = 0}//kotlin 寫法二:c = try {a/b}catch (e:Exception){e.printStackTrace()0}}

在這里插入圖片描述
三丶運算符與中綴表達式

package com.wangrui.kotlin.chapter03fun main(){/*運算符*/
//1、== 與 equals 等價
//2、+ 與 plus 等價
//3、in 與 contarins 等價
//4、[] 與 get、set等價
舉例一:val value = map["Hello"]等價于val value = map.get("Hello")*/舉例二:map["Hello"] = 4map.set("Hello",4)*/
//5、> 與 compareTo 等價
//6、() 與 invoke/*中綴表達式 '.xx'*///1、 to 等價于 .to
//    舉例:
//        2to3    等價于 2.to(3)//2、 .on
}

在這里插入圖片描述
四丶Lambda 表達式

package com.wangrui.kotlin.chapter04fun main(){/*匿名函數的傳遞*/val func = fun(){println("Hello")}/*匿名函數的類型*/val func:()->Unit = fun(){println("Hello")}/*Lambda 表達式的類型*/val lambda:()->Unit = {println("Hello")}Java的Lambda 使用代碼:
//  定義接口,并且只有一個方法interface Function1{void invoke(int p)}//使用LambdaFunction1 f1 = (p) -> {System.out.println(p);}/*Lambda 表達式的類型*///寫法一:val f1:(Int)->Unit = {p:Int ->println(p)}//寫法二://原理:表達式參數類型從表達式類型推斷而來val f1:Function<Int,Unit> = {p ->println(p)}//寫法三://原理:表達式的類型從聲明推斷而來val v1 = {p:Int ->println(p)}//舉例:val v1 = {p:Int ->println(p)"Hello"    //表達式的最后一行為返回值}/*Lambda 表達式的參數省略形式*/val f1:Function<Int,Unit> = {//如果Lambda表達式只有一個參數,參數名可默認為itprintln(it)}}

在這里插入圖片描述

五丶本章小結

在這里插入圖片描述

2.6、高階函數

一丶高階函數

package chapter01// region + 折疊
fun main(){/*高階函數的調用*///如果括號里的函數類型作為最后一個參數,可移到括號外面//it 是Lambda的特性intArray.forEach(){println("Hello $it")}//等價于intArray.forEach{println("Hello $it")}}
// endregion/*高階函數*/
// region + 折疊
//特征一:  block:()->Unit  ——  參數包含函數類型
//特征二:返回值為函數類型
fun needsFunction(block:()->Unit){block()
}
// endregion//  常見的高階函數一:
//IntArray.forEach  ——  擴展方法
//action:(Int) -> Unit  ——  接收函數類型作為參數
inline fun IntArray.forEach(action:(Int) -> Unit):Unit{//action(element)   ——  調用函數actionfor(element in this) action(element)
}//  常見的高階函數二:
//R ——  返回值元素類型
//transform:(Int)->R    ——  接收函數類型作為參數
inline fun <R>IntArray.map(transform:(Int)->R):List<R>{//transform ——  進一步傳遞 transformreturn mapTo(ArrayList<R>(size),transform)
}

在這里插入圖片描述

二丶內聯函數

package chapter02fun main(){/*內聯函數的概念*///通過 inline標記val ints = intArrayOf(1,2,3,4)ints.forEach {println("Hello $it")}/*內斂高階函數的return*/val ints = intArrayOf(1,2,3,4)ints.forEach {//return@forEach 跳出這一次內聯函數調用 與 Java Continue 一樣if (it == 3)return@forEachprintln("Hello $it")}/*non-local return*/nonLocalReturn {return //△表示:并不是退出Lambda表達式,而是從 外部 函數(main)返回}}inline fun IntArray.forEach(action:(Int)->Unit):Unit{for (element in this) action(element)
}/*定義內聯函數*/
inline fun hello(){println("Hello")
}/*non-local return*/
inline fun nonLocalReturn(block:()->Unit){block()
}/*non-local return*///不合法的情況
inline fun Runnable(block: () -> Unit):Runnable{return object :Runnable{override fun run() {//不合法處原因:1、有可能存在不合法的 non-local return2、因為 block 的調用處與定義處不在同一個調用上下文//其實return 的是 run 而不是Runnableblock()}}}//解決方法一:
//禁止 non-local return
inline fun Runnable(crossinline block: () -> Unit):Runnable{return object :Runnable{override fun run() {block()}}
}//解決方法二:
//禁止函數參數被內斂
inline fun Runnable(noinline block: () -> Unit):Runnable{return object :Runnable{override fun run() {block()}}
}/*內聯屬性*/
//含義:  沒有 backing-field 的屬性 getter/setter 可以被內聯
//舉例:
var pocket.Double = 0.0
var money.Doubleinline get() = pocketinline set(value){pocket = value}/*內聯函數的限制*/
//1、public/protected 的內聯方法只能訪問對應類的 public 成員
//2、內聯函數的內聯參數不能被存儲(賦值給變量)
//3、內聯函數的內聯函數參數只能傳遞給其他內聯函數參數

在這里插入圖片描述

三丶幾個有用的高階函數

package chapter03import java.io.Filefun main(){val person = Person("benny",20)//let舉例:返回表達式結果// '::' 表示把一個方法當做一個參數,傳遞到另一個方法中進行使用,通俗的來講就是引用一個方法person.let(::println)//run舉例:返回表達式結果person.run(::println)//also舉例:返回Receiverval person2 = person.also {it.name = "hhh"}//apply舉例:返回Receiverval person3 = person.apply {name = "xxx"}//use舉例:自動關閉資源File("build.gradle").inputStream().reader().buffered().use {println(it.readLine())}}/*幾個有用的函數*/
//  let、run、also、apply、use
//舉例class Person(var name:String,var age:Int){}

在這里插入圖片描述

四丶集合變化與序列

package chapter04import java.lang.StringBuilderfun main(){/*filter 變換(序列)*///Java版本:list.stream().filter(e->e%2 == 0)
//    等價于//kotlin版本一://asSequence()轉換為懶漢式list.asSequence().filter{it % 2 == 0}//kotlin版本二:list.filter{it % 2 == 0}/*map 變換*///Java版本:list.stream().filter(e->e%2 == 0)//kotlin版本一:list.map{it*2+1}//kotlin版本二:list.asSequence().map{it*2+1}/*flatMap變換*/
//    flatMap概念:用一個元素映射成一個集合,再把這個集合拼接起來得到新的集合
//    Map概念:把里面的元素映射成新的元素,那么這些元素組成的集合就成為Map集合
//    寫法一:val list = listOf(1,2,3,4)list.flatMap {(0 until it)}.joinToString().let(::println)//    寫法二:list.asSequence()       //將集合變成一個序列.flatMap {(0 until it).asSequence()   //結果也應該要變成一個序列}.joinToString().let(::println)/*集合的聚合操作舉例*///1、sum —— 所有元素求和//2、reduce 將元素一次按規則聚合,結果于元素類型一致//3、fold —— 給定初始化值,將元素按規則聚合,結果與初始化值類型一致/*fold操作*///acc —— 每一次拼接后的結果//i —— 遍歷的list集合里的每一個元素list.fold(StringBuilder()){//acc.append(i) —— 返回值類型為StringBuilder,作為下一個元素的 accacc,i -> acc.append(i)}/*惡漢式舉例*///概念:會分別在filter里馬上遍歷List集合,在往下走到map集合時就會馬上調用list進行映射,再到forEach//區別:filter{}與map{}還有flatMap{}會立即調用//代碼運行結果:0 1 2 3 4 0 1 2 3 4 5 6 7 8list.filter {it % 2 == 0}.map {it * 2 + 1}.flatMap {0 until it}.forEach(::println)/*懶序列舉例:*///概念:集合里的元素只有通過了一個才能繼續往下走//區別:forEach 時才會調用filter{}與map{}還有flatMap{}//forEach —— 在這里就像是一個鑰匙,如果沒有這句代碼打開水管,那上面的三個函數就像被堵住一樣都不會調用//代碼運行結果:0 1 2 3 4 0 1 2 3 4 5 6 7 8list.asSequence().filter {it % 2 ==0}.map {it *2 +1}.flatMap {(0 until it).asSequence()}.forEach(::println)}

在這里插入圖片描述

五丶SAM 轉換

package chapter05fun main(){//Java中的lambda表達式是沒有自己的類型的,而且只能接口里只能有一個方法//kotlin實際上時創建一個 Runnable 包裝了一下Lambda,并非直接轉換
}

在這里插入圖片描述

六丶案例:統計字符個數

package chapter06import java.io.Filefun main(){//打開文件build.gradle,閱讀文本,string 類型File("build.gradle").readText().toCharArray()  //把它們char類型數組.filter { !it.isWhitespace() }  //過濾空白字符.groupBy { it } //it 是charArray里的每一個字符,通過it來分組,得到key 就是 char.map {it.key to it.value.size     //映射}.let {print(it)}
}

七丶本章小結

在這里插入圖片描述

3、Kotlin 知識體系

在這里插入圖片描述

4、為什么要學習 Kotlin

  • (1)Google 在2019年的I/O大會上宣布,Kotlin 已經成為 Android 的第一開發語言
  • (2)Google Play 商店中排名前1000的 App里,有超過 60% 的 App 已使用 Kotlin語言。
  • (3)未來提供的官方 API 也將會有優先考慮 Kotlin 版本。
  • (4)Android 官網文檔的代碼已優先顯示 Kotlin 版本,官方的視頻教程以及一些開源項目也已改成 Kotlin 來實現。

5、Kotlin 的工作原理

首先,你先要知道 Java語言的運行機制,請閱讀 我寫的—Java 的運行機制 這篇博客!Kotlin的工作原理其實和Java工作原理一樣的

6、Kotlin 的優點

  • (1)語法更為簡介,同樣的功能Kotlin 開發要比Java 少 50% 甚至更多。
  • (2)增加了許多現代高級語言的語法特性,使得開發效率大大提升。
  • (3)幾乎杜絕了空指針這個全球崩潰率最高的異常。
  • (4)Kotlin 和 Java 是100% 兼容的 Kotlin可以直接調用和使用 Java 編寫的代碼,也可以無縫使用 Java 第三方開源庫。

7、輸出“Hello World”

(1)創建一個Kotlin編寫的 Android工程,步驟如下

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

(2)代碼

Kotlin 每一行代碼結尾都不用加分號

fun main(){println("Hello World")
}

點擊小圖標,選擇Run運行
在這里插入圖片描述
在這里插入圖片描述
(3)運行結果
在這里插入圖片描述

原創不易,希望能得到一個贊,感謝各位!

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/194741.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息