参考地址
参考地址: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. 语法和标识符
记得太长了,这部分换一篇继续。