目录
- val,var关键字
- 函数
- Lambda表达式
- 类成员
- 运算符
- 表达式
- 循环语句(for循环,while循环,continue,break)
- 异常捕获
- 具名参数,变长参数,默认参数
val,var关键字
kotlin中关键字val用来表示常量,var用来表示变量
val a : String = "Hello world"
var b : String = "Hello world"
a的值不能改变,b的值可以改变
另外,kotlin中有类型推导的功能,可以不用写String类型例如下面这样
val c = "Hello world"
可以推倒出c是String类型.
kotlin中的val和java中的final有什么区别?
java中的final是编译期常量,什么是编译期常量?就是在编译的时候就把引用换成值。而kotlin中的val修饰的只是一个不能改变值的变量(可以通过反射改变),如果我们想要在kotlin中定义编译期常量我们可以加上const关键字.
函数
kotlin中函数定义
fun main(args: Array<String>) : Unit{
}
Unit是返回类型,它相当于java中的Void关键字声明
fun sum(arg1 : Int,arg2: Int) : Int{
return arg1 + arg2
}
当然也是可以返回其它的类型
fun main(args: Array<String>) : Unit{
val arg1 = args[0].toInt()
val arg2 = args[1].toInt()
println("$arg1 + $arg2 = ${sum(arg1,arg2)}")
}
对于返回值只有一个表达式的函数还可以简写成:
fun sum(arg1 : Int,arg2: Int) = arg1 + arg2
匿名函数
val int2Long = fun(arg : Int) : Long{
return arg.toLong()
}
Lambda表达式
关于Lambda表达式请参见 :https://www.jianshu.com/p/78f7c6d169f2
类成员
如何在kotlin中声明一个类
class MM(name : String,age : Int,voice : String){
fun sing(name : String){
println("sing $name")
}
}
声明及使用
fun main(args: Array<String>) {
val mm = MM("",22,"未知")
mm.sing("天鹅湖")
}
在java中声明一个成员变量,通常会有set和get方法如下
public class JavaA {
private int b = 0;
public int getB() {
System.out.println("some one tries to get b.");
return b;
}
public void setB(int b) {
System.out.println("some one tries to set b.");
this.b = b;
}
}
但是在kotlin中默认是不需要set和get方法的
open class A{
var b = 0
}
直接就可以使用
var a : A = A()
a.b
这和java中声明成员变量为public差不多. 其实也是可以设置get/set方法的,如下
open class A{
var b = 0
get() = field
set(value){ field = value}
}
另外,kotlin中存在一种延迟加载的机制,var可以用lateinit关键字,val可以用lazy关键字.
open class A{
var b = 0
lateinit var a : String
lateinit var d : X
val e : X by lazy{
println("init X")
X()
}
}
运算符
在java当中,运算符都是定死的,+-*/, 1+1一定等于2,但是在kotlin中运算符是可以自定义的,也就是说1+1可以不等于2.
官网详情:https://kotlinlang.org/docs/reference/operator-overloading.html
下面我们自定义加法运算符,做一个复数相加的运算
class Complex(var real:Double,var imaginary:Double){
operator fun plus(other:Complex) : Complex{
return Complex(real+other.real,imaginary+other.imaginary)
}
override fun toString(): String {
return "${real}+${imaginary}"
}
}
fun main(args: Array<String>) {
val c1 : Complex = Complex(3.0,4.0);
val c2 : Complex = Complex(4.0,5.0);
println(c1 + c2)
}
最终输出
7.0+9.0i
运算符重写只对参数个数做要求,对参数和返回值类型不做要求
例如我可以重写plus如下:
operator fun plus(other:Int) : Complex{
return Complex(real+other,imaginary+other)
}
operator fun plus(other:Int) : Int{
return other
}
以上都是可以的, 另外我们再来看看infix中缀表达式
if ("-name" in args){
}
使用in其实是关联到了Array中的contains函数,他返回是否存在该元素
public operator fun <@kotlin.internal.OnlyInputTypes T> Array<out T>.contains(element: T): Boolean {
return indexOf(element) >= 0
}
我们也可以使用infix定义其它的运算符号如 on.
class Desk
class Book{
infix fun on(desk: Desk):Boolean{
return false
}
}
fun main(args: Array<String>) {
val d = Desk()
val b = Book()
if (b on d){
}
}
表达式
if表达式可以有返回值
class Kotlin{
val DEBUG = 1
val USER = 2
fun test(){
var rule = true
var mode = if (rule){
DEBUG
}else{
USER
}
}
}
when表达式
java中的swich表达式针对的类型有限(只能和int类型兼容,1.7增加了String和枚举),在kotlin中使用when来替代swich表达式
fun test(){
val x = 5
when(x){
is Int -> println("Hello $x")
in 1..100 -> println("$x is in 1..100")
!in 1..100 -> println("$x is not in 1..100")
}
}
同时when也是有返回值的
fun test(){
val a = A()
var mode = when {
a == null -> 1 else ->0
}
}
循环语句(for循环,while循环,continue,break)
for循环的几种基本形式
val array = intArrayOf(1, 2, 3)
for (arg in array){
println(arg)
}
for ((index,value) in array.withIndex()){
println("$index -> $value")
}
for (indexValue in array.withIndex()){
println("${indexValue.index} -> ${indexValue.value}")
}
关于in操作符
image.png
可以看出in操作符的对象必须满足实现以上三个方法,下面我们来自定义迭代类,然后使用in进行迭代输出
class MyIterator(val iterator: Iterator<Int>){
operator fun next(): Int{
return iterator.next()
}
operator fun hasNext(): Boolean{
return iterator.hasNext();
}
}
class MyIniList{
private val list = ArrayList<Int>()
fun add(int : Int){
list.add(int)
}
fun remove(int : Int){
list.remove(int)
}
operator fun iterator():MyIterator{
return MyIterator(list.iterator())
}
}
最终输出
val list = MyIniList()
list.add(1)
list.add(2)
list.add(3)
for (arg in list){
println(arg)
}
while语句
var x = 5
while (x > 0){
println(x)
x--
}
do {
println(x)
x--
}while (x > 0)
continue,break
class Loop2{
class Student{
fun isNotClothedProperly():Boolean{
return false
}
}
fun test(){
val students = ArrayList<Student>()
val you = Student()
for (student in students){
if (student == you) continue
if (student.isNotClothedProperly()){
break
}
}
}
}
异常捕获
class Sum{
fun input(args :Array<String>){
try {
val arg1 = args[0].toInt()
val arg2 = args[1].toInt()
println("$arg1+$arg2=${arg1+arg2}")
}catch (e : NumberFormatException){
println("您确定输入的是整数吗?")
}catch (e : ArrayIndexOutOfBoundsException){
println("您确定输入的是两个整数吗?")
}catch (e : Exception){
println("程序出现了未知异常.${e.message}")
}finally {
println("谢谢使用")
}
}
}
具名参数,变长参数,默认参数
具名参数
具名参数的意思是,在传入参数的同时给定参数名字
class Test{
fun test(){
sum(arg2 = 3,arg1 = 2)
}
fun sum(arg1 : Int, arg2 : Int){
}
}
变长参数
参数的个数可以任意改变
class Test{
fun test(){
hello(1,2,3,4,5,string = "hello")
}
fun hello(vararg ints : Int, string: String){
ints.forEach(::println)
}
}
变长参数还支持一个特性
fun test(){
val array = intArrayOf(1,3,4,5)
hello(*array,string = "hello")
}
*表示把数组展开成一个个元素传进去.
默认参数
默认参数参数可以给参数设定一个默认值,调用函数的时候可以不用传该参数,具体使用如下
class Test{
fun test(){
val array = intArrayOf(1,3,4,5)
hello(ints = *array,string = "hello")
}
fun hello(double: Double = 3.0,vararg ints : Int, string: String){
ints.forEach(::println)
}
}
以上是我对kotlin中程序结构相关内容的总结.
网友评论