“用Kotlin开发android更简洁( ̄_, ̄ )”
基本语法
变量的定义
val x: Int = 5//var是申明只读变量,通过:X后面指定变量类型,相当于final
val x = 5//可以自行推导出类型
val x : Int//没有初值时
var x = 5//可变变量
x+=1
数据模型的定义
我们经常创建一个只保存数据的类。在这样的类中一些函数只是机械的对它们持有的数据进行一些推导。在 kotlin 中这样的类可以标注为 data
data class User(//通过构造函数的方式
var name: String = "",
var age: Int = 0,
var email: String = ""
}
可以看下data是什么作用
相比之下,增加了component、copy数据处理方法
component1 相当于获取构造函数里第一个值component2依次类推//相当于get方法
copy:
val user = User("A", 2, "562401002@qq.com")
user = new User()//创建空对象需要给构造函数指定默认值
var usr = user.copy(age = 1)//可以根据key值替换所要更换的值
usr = user.copy("B")//也可以根据构造函数的顺序来
usr = user.copy()
属性申明
private -- 只在声明的范围和同一个模块的子范围可见;
protected -- (只可以用在类或接口的成员上)和 privete 很像,但在子类中也可见;
internal -- (默认使用) 在同一个模块中都可见;
public -- 在任何地方均可见;
函数方法的定义
//参数:类型 返回类型也基本和java语法相反
fun sum(a: Int, b: Int): Int {
var sum = a + b
return sum
}
fun sum2(a: Int, b: Int): Int = a + b
fun sum3(a: Int, b: Int) = a + b //最简形式
字符串模板表达式
字符串可以包含模板表达式。一个模板表达式由一个 $ 开始并包含另一个简单的名称:
val i = 10
val s = "i = $i" // 识别为 "i = 10"
//或者是一个带大括号的表达式:
val s = "abc"
val str = "$s.length is ${s.length}" //识别为 "abc.length is 3"
var name1 = user.name
var name2 = usr.name
var sum = "$name1 和 $name2 的年龄之和为 ${sum(user.age, usr.age)}"
this.log(sum)
Array的使用
Arrays在 Kotlin 中由 Array 类表示,有 get 和 set 方法(通过运算符重载可以由[]调用),以及 size 方法,以及一些常用的函数:
class Array<T> private () {
fun size(): Int
fun get(index: Int): T
fun set(Index: Int, value: T): Uint
fun iterator(): Iterator<T>
//...
}
val b: Byte = 0
var i: Int = b.toInt() //显式转换
var str: String = "hello word ! \n"
this.log(String.format("$str has word is %b \n", str.compareTo("word")))
var array = ArrayList<User>()
// var arry: Array<User> = emptyArray() //返回指定类型空数组,指定大小为0,不能添加?
var arry: Array<User?> = arrayOfNulls(str.length)
for (c in str) {
var name = c.toString()//需要char 转string
var user = User(name, i + 1, "")
this.log(user.name)
arry.set(i++, user)//和java不同,没有add方法,需要预先指定大小
}
this.log("size = " + arry.size + "\n")
空安全调用操作符
在许多语言中都存在的一个大陷阱包括 java ,就是访问一个空引用的成员,结果会有空引用异常。在 java 中这就是 NullPointerException 或者叫 NPE
在 Kotlin 类型系统中可以为空和不可为空的引用是不同的。比如,普通的 String 类型的变量不能为空:
var a: String ="abc"
a = null //有些会产生空异常的行为都会导致编译错误
允许为空,我们必须把它声明为可空的变量:
var b: String? = "abc"
b = null
三种操作符!! ?. ?; 举个例子:
var tv: TextView ? = null
var btn_sample_1: Button? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv = findViewById(R.id.tv) as TextView?
// btn_sample_1 = findViewById(R.id.btn_sample_1) as Button?//此处注掉
tv!!.text = "Hello MyKotlin"
(tv as TextView).textSize = 20.0f
//首先是!! 操作符
btn_sample_1!!.setOnClickListener {
v: View ->
startActivity(Intent(this, SampleActivity1::class.java))
}
//这种情况下,程序会抛出异常 ERROR!!!,跟java一样的情况,不多解释
//然后是?.操作符
btn_sample_1?.setOnClickListener {
v: View ->
startActivity(Intent(this, SampleActivity1::class.java))
}
//遇到异常时,不会往下执行
//最后是 ?; 操作符(Elvis 操作符)
val l = b.length()?: -1
//如果 ?: 左边表达式不为空则返回,否则返回右边的表达式。注意右边的表带式只有在左边表达式为空是才会执行
}
安全转换
普通的转换可能产生 ClassCastException 异常。另一个选择就是使用安全转换,如果不成功就返回空:
val aInt: Int? = a as? Int
流程控制(表达式)
if表达式
var a: Int = 1
var b: Int = 2
//传统用法
var max: Int = a
if (a < b)
max = b
//带 else
if (a > b) max = a
else max = b
//作为表达式 返回最后的值,和java的唯一的区别
max = if (a > b) a else b
max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
When 表达式,代替switch,相比swith更加的简洁(可以告别java里的if else if)
var randInt = Random().nextInt(10)
var rand = when (randInt) {
1 -> {
this.log("randInt =1")
randInt
}
2, 3 -> {
this.log("randInt = 2 or 3") //多分支处理
randInt
}
in 4..6 -> {
this.log("randInt in 4-6") //区间检查
randInt
}
else -> {
this.log("randInt = other:" + randInt)
randInt
}
}
//当做if else if 表达式
when {
rand in 0..5 -> this.log(" in 0-5")
rand == 6 -> this.log(" is 6")
else -> this.log(" is other")
}
for 循环,三种用法
var users: Array<User?> = arrayOfNulls(10)
for (i in users.indices) {
//通过索引迭代
var usr = User("" + i, i + 1, "")
// usr.name = null!!//抛出KotlinNullPointerException
users.set(i, usr)
}
for (user in users) {//通过任何提供的迭代器进行迭代
this.log("name=" + user?.name + "age:" + user?.age)//空安全调用操作符
}
var ints: Array<Int?> = arrayOfNulls(5)
for (item: Int? in ints) {//内容可以是一个语句块
//...
}
关于迭代方式,Array提供了一种forEach 的使用方法能够完成遍历
users.forEach {
this.log("i:" + it?.name + "size=" + users.size)
if (it?.age == 3) {
this.log("return" + it?.age)
return
}
}
while 循环 使用方式和往常一样
返回与跳转
@标签的使用,可以决定 在哪break或者continue
loop@for (i in 1..10) {
for (j in 1..10) {
if (j == 6) {
this.log(" break i=" + i + "j=" + j)
break@loop //不加标签则结束本次循环
}
this.log("i=" + i + "j=" + j)
}
}
也可以用函数名代替表达式名,返回到标签处
fun foo() {
var users: Array<User?> = arrayOfNulls(10)
for (i in users.indices) {
var usr = User("name" + i, i, "")
users.set(i, usr)
}
users.forEach {
this.log("i:" + it?.name + "size=" + users.size)
if (it?.age == 3) {
this.log("return" + it?.age)
return@forEach
}
}
}
这边是完整的Demo ,后面继续学习kotlin的类和对象