參考地址
參考地址:Kotlin流程控制語句筆記
學習書籍:《Kotlin極簡教程》
Kotlin
1. 新建Kotlin項目
出現異常,下載不下來
Could not resolve org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.61.
切換到在線模式,修改project的gradle
buildscript {
ext.kotlin_version = '1.2.61'
repositories {
// google()
// jcenter()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven{ url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
// google()
// jcenter()
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven{ url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
google()
maven { url 'https://jitpack.io' }
}
}
MainActivity代碼如下:
package com.yoshin.company.kotlin2app
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
2. 變量類型
2.1 變量和常量
kotlin 中使用 var和val聲明變量。
語法:
val | var 變量名 [: 變量類型] [= 值]
也可以寫成:
val | var 變量名 [: 變量類型]
此處變量會根據類型設置默認值
val | var 變量名 [= 值]
此處省略了類型
例如下:
val name: String = "yoshin"
var age: Int = 12
var compary: String = "國有企業"
var compary3: Int
compary3 =123123
var compary4 = "1";
2.2 Any 父類
對比JAVA:
當 Kotlin 函數中使用 Any 時,它會被編譯成 Java 字節碼中的 Object
理解用途:
Any 類型是 Kotlin 中 所有非空類型(ex: String, Int) 的根類型。
Any?
用途:可空的根類型
那麼Any和Any?誰是父類的根類型呢?
答:Any?
參考地址:Dive Into Kotlin(四):爲什麼 Kotlin 的根類型是「Any?」
2.3 is 類型檢測
用途:
is運算符檢測一個表達式 是否爲 某類型的一個實例
如果檢測後,可以判斷爲某一類型,那麼可以直接使用該類型而不需要顯示轉換
例:
fun getLength(obj: Any) {
if (obj is String) {
Log.i(TAG,obj)
}else
Log.i(TAG,obj)
}
我們知道 Log.i(TAG,obj) 裏面的obj應該是string類型纔可以調用。在 obj is String 內的Log.i(TAG,obj) 就可以正常調用,但是else內的就會報錯,不讓這麼寫。
3. 字符串與模板表達式
轉義字符:
轉義字符不沿用java的寫法,而是通過 “”“ ”“”
六個引號,引用。
例:
代碼:
val shenglue = """
fun getLength(obj: Any) {
if (obj is String) {
Log.i(TAG,obj)
}
// Log.i(TAG,obj)
}"""
println(shenglue)
上述代碼,其實只是定義一個常量,並打印。
輸出Log:
I/System.out: fun getLength(obj: Any) {
I/System.out: if (obj is String) {
I/System.out: Log.i(TAG,obj)
I/System.out: }
I/System.out: // Log.i(TAG,obj)
I/System.out: }
如小括號和大括號都可以直接輸出出來。
字符串插入代碼:
如圖:
val shenglue = """${name.length}"""
println(shenglue)
使用:
“”"${ content }"""
4. 流程控制語句
if語句
if在kotlin的使用中存在返回值,java中沒有
作爲表達式(三元表達式):
var obj2 = if (a > b) 1 else 3
作爲代碼塊:
var obj2 = if (a > b) {
println("""${name.length}""")
1
} else {
println("""${name.length + 1}""")
3
}
最後一行必須爲該塊的返回值.
when表達式
用途:
功能類似switch-case.
作爲表達式:
val hasPrefix = when (x) {
is String -> x.startsWith("prefix")
else -> false
}
作爲代碼塊和表達式:
val validNumbers = 19;
fun getU(x: Int): Int {
return when (x) {
in 1..10 -> {
println("x is in the range")
1
}
validNumbers -> {
println("x is valid")
2
}
in 10..20 -> {
println("x is outside the range")
3
}
else -> {
println("none of the above")
4
}
}
}
println( getU(12))
for循環
Kotlin的for循環與現代的程序設計語言基本相同
for循環有三種循環方法,如下:
迭代器
for循環可以對任何提供迭代器(iterator)的對象進行遍歷,語法如下:
for(item in collection){
//操作item
println(item)
}
類似JAVA增強for循環
索引遍歷
通過索引遍歷數組或者List,語法如下:
for(i in args.indices){
print(array[i])
}
功能類似JAVA普通循環
庫函數操作(withIndex)
for((index,value) in array.withIndex()){
print("the element at $index is $value")
// index//下標
// element//值
}
有點增強for循環加PTfor循環組合到一起的感覺,同時獲得兩個值。
while 循環
和JAVA、C基本一致
var c = 2
while (c > 0){
c--
}
var dow = 0;
do {
dow++
} while (dow < 9)
break和continue
break. 結束最內層的循環.
return. 默認行爲是, 從最內層的函數或 匿名函數 中返回.
continue. 在最內層的循環中, 跳轉到下一次循環.
跟JAVA一致
return
函數返回值:
1.類似JAVA的用法
fun sum(x: Int, y: Int): Int {
return x + y
}
fun max(a: Int, b: Int): Int {
if (a > b) return a else return b
}
2.使用“=”代替return
可以直接使用=符號直接返回一個函數的值
fun dive(a: Int, b: Int): Int = a / b
標籤 label
用途:可以控制 return、break、continue他們的跳轉行爲。
場景:
在Kotlin中任何表達式都可以用標籤標記;
標籤的格式:
標識符後跟@符號,如:abc@、jarOfLove@
調用時:
@abc、@jarOfLove
標記的例子:
顯示標籤的例子:
fun returnDemo3() {
println(" start " + ::returnDemo3.name)
val intArray = intArrayOf(1, 2, 3, 4, 5)
intArray.forEach here@{
if (it == 3) {
return@here
}
println(it)
}
}
隱式標籤的例子:
fun returnDemo4() {
println(" start " + ::returnDemo4.name)
val intArray = intArrayOf(1, 2, 3, 4, 5)
intArray.forEach {
if (it == 3) {
return@forEach
}
println(it)
}
}
因爲,不管加不加標籤都不會影響功能,所以,這裏的標籤只有標記以便於之用途
改變功能的例子:
標籤不只是能增加代碼可讀性,還可以改變實際功能。
label配合break的使用
寫了三個方法爲了對比一致label的位置對break的影響:
private fun returnDemo3() {
println(" start " + ::returnDemo3.name)
for (outer in 1..5) {
println("outer ==$outer")
for (inner in 1..10) {
println("inner ==$inner")
if (inner % 2 == 0) {
break
}
}
}
}
private fun returnDemo4() {
println(" start " + ::returnDemo4.name)
for (outer in 1..5) {
println("outer ==$outer")
here@ for (inner in 1..10) {
println("inner ==$inner")
if (inner % 2 == 0) {
break@here
}
}
}
}
private fun returnDemo5() {
println(" start " + ::returnDemo5.name)
here@ for (outer in 1..5) {
println("outer ==$outer")
for (inner in 1..10) {
println("inner ==$inner")
if (inner % 2 == 0) {
break@here
}
}
}
}
調用:
returnDemo3()
returnDemo4()
returnDemo5()
Log輸出:
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: start returnDemo3
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==3
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==4
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==5
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: start returnDemo4
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==3
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==4
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==5
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: start returnDemo5
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: outer ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==1
2020-07-02 09:28:49.086 6717-6717/com.yoshin.company.kotlin2app I/System.out: inner ==2
通過Log分析:
可以看到我們的方法returnDemo3和returnDemo4是輸出一樣的Log。通過代碼也可以看到,returnDemo4裏label的作用就是跳出當前循環,這和returnDemo3裏break的基礎用法是一致的。
returnDemo3和returnDemo5輸出不一致。returnDemo5方法內,可以看到標籤標記在了最外層循環上,這意味着break的作用是終止最外層循環?
分析一下returnDemo5的代碼,如果當break調用後,作用到最外層循環上,應該輸出Log:
I/System.out: outer ==1
I/System.out: inner ==1
I/System.out: inner ==2
這與我們實際打印出來的Log是一致的。
所以結論,break@lable 會終止 label@ 所在的循環(也會終止內部循環)
label配合return的使用
沒有看出有啥用,再說吧!
記住:return是跳出方法,而lable就是隻能在一個方法內使用,所以return是不是和lable配合不了?
那麼能不能通過lable和return配合,讓return不退出方法內,嘗試下:
fun run() {
for (outer in 1..5) {
println("outer ==$outer")
for (inner in 1..10) {
println("inner ==$inner")
here@ if (inner % 2 == 0) {
return@here
}
}
}
println("run end")
}
println("returnDemo6 end")
}
private fun returnDemo7() {
println(" start " + ::returnDemo7.name)
here@ fun run() {
for (outer in 1..5) {
println("outer ==$outer")
for (inner in 1..10) {
println("inner ==$inner")
if (inner % 2 == 0) {
return@here
}
}
}
println("run end")
}
println("returnDemo7 end")
}
調用:
println("------------------")
returnDemo6()
returnDemo7()
Log:
2020-07-02 10:08:24.535 9444-9444/? I/System.out: ------------------
2020-07-02 10:08:24.535 9444-9444/? I/System.out: start returnDemo6
2020-07-02 10:08:24.535 9444-9444/? I/System.out: returnDemo6 end
2020-07-02 10:08:24.535 9444-9444/? I/System.out: start returnDemo7
2020-07-02 10:08:24.535 9444-9444/? I/System.out: returnDemo7 end
好像沒啥用。
目前結論是:label和return配合沒啥用
label配合return以及lamda的使用
private fun returnDemo6() {
println(" start " + ::returnDemo6.name)
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return
println(it)
}
println("returnDemo6 end")
}
private fun returnDemo7() {
println(" start " + ::returnDemo7.name)
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit
println(it)
}
println("returnDemo7 end")
}
調用:
println("------------------")
returnDemo6()
returnDemo7()
輸出:
2020-07-02 10:21:55.514 12304-12304/com.yoshin.company.kotlin2app I/System.out: ------------------
2020-07-02 10:21:55.514 12304-12304/com.yoshin.company.kotlin2app I/System.out: start returnDemo6
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: 1
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: 2
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: start returnDemo7
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: 1
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: 2
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: 4
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: 5
2020-07-02 10:21:55.515 12304-12304/com.yoshin.company.kotlin2app I/System.out: returnDemo7 end
returnDemo7中:可以看到return跳過了當前循環,沒有退出方法,而是繼續運行
label和continue的使用
TODO 沒有找到例子,再說
throw 表達式
Kotlin中的throw 表達式,它的類型是特殊類型:Nothing,該類型沒有值。與JAVA、C中的void一個意思。
用途:輸出異常信息
例:
private fun testThrow(msg: String){
throw IllegalArgumentException(msg)
}
//調用
testThrow("輸出錯誤信息")
Caused by: java.lang.IllegalArgumentException: 輸出錯誤信息
at com.yoshin.company.kotlin2app.MainActivity.testThrow(MainActivity.kt:61)
at com.yoshin.company.kotlin2app.MainActivity.onCreate(MainActivity.kt:57)
如果要接throw表達式的值,可以這麼寫:
private fun testThrow(msg: String): Nothing{
throw IllegalArgumentException(msg)
}
val no: Nothing = throw Exception("test")
接收好像是沒啥用,反正會異常退出。
5. 代碼註釋
和JAVA JavaScript 類似,多了一個多層嵌套
6. 語法和標識符
記得太長了,這部分換一篇繼續。