kotlin基础语法,kotlin 语法
Kotlin 基础语法知识
Byte、Short、Int、Long、Float、Double 等。不同于 Java 的是,字符不属于数值类型,是一个独立的数据类型
赋值转换 toInt(): Int? ? toLong():Long? ? toFloat():Float? ? ?toDouble():Double? ? ?toChar(): Char?
大宽度转小宽度精度丢失
1.1 整数类型:Byte、Short、Int、Long? ? ? ?
未超出Int 最大值默认为Int,超出默认为Long
var a = 1 (Int )
var b =300000000000000? ? ? (Long? 超出 Int 的最大值)
1.2 浮点类型 :Double、Float
var a =3.14? (Double)
var b = 2.7184545 (Double)
var c = 2.2145456454547854f? (Float, 实际值为 2.2145456, 十进制最多包含6~7位数,会舍入)
1.3 字符类型:Char? 字符类型可以转换为其他类型
?var char = 'a'
var a = char.toLowerCase()? (小写转换)
var A = char.toUpperCase()? (大写转换)
1.4 布尔类型
val m =true?val n =false
可变变量定义:var 关键字? 可读写
不可变变量定义:val 关键字 (类似于java: final)只读不写
常量: const 大写格式
用冒号 : 隔开,可省略类型直接赋值
2.1? 关键字 标识符 : 类型 = 初始化值? ? ?
var a: Int = 1? ?
2.2? 声明时初始初始化未设置类型?
var a = 1? ?(系统自动判断设置为int)
var a = "str"? ? ?(系统自动判断设置为字符串)
2.3??声明时初始初始化只提供类型
var a:? Int??
a = 1 (赋值)
a +=1 (修改变量)
2.4? ? $:表示一个变量名或者变量值? ? ?
var a= "a is"
var b =? $a? ? ?$varName 表示变量值??
val b = "${a.replace("is", "was")}"? ???${varName.fun()} 表示变量的方法返回值??( b值为a was)
2.5? 静态常量赋值
const val a =1
构成:关键字声明+函数名+参数+返回类型+ 函数体,Kotlin函数默认修饰符public
3.1 无参数函数
fun sum(){ }
3.2 无返回值函数
fun sum(a: Int, b: Int): Unit {
????print(a + b)}
}
3.3 有返回值函数
fun sum(a: Int, b: Int): Int {
? ? c = a + b
? ? return c
}
3.4 单表示式函数:省略花括号
fun sum(a: Int, b: Int) = a+b
fun main(){? ?
?val a :ArrayInt = arrayOf(1,2,3)
}
ArrayAny 任意类型
1.for ( int i=1 ;? i=100 ; i++? )? ? ------? ? ? ?for ( i in 1..100 )
2.? ?for ( int i=100 ;? i=100 ; i--? )? ? ------? ? ? ?for ( i? in ?100 downTo 1 )
3.迭代器(iterator) for(int item: list)? ? ------? ? ? ?for (item in list?)
class Name{? ? ?(定义一个name的类)
????var a: String = "a" (类的属性)
? ? val b: Int = 1;
}
fun main(){
var name: Name= Name()? ? ?(构造函数创建类实例)
name.a = "a is"? ? ? ? (赋值)
}
选择排序:
java:
kotlin :
Kotlin基本语法之(四)成员变量与get、set方法
在之前的文章中我们讲到,Kotlin类中的属性既可以用关键字 var 声明为可变的,也可以用关键字 val 声明为只读的。
默认情况下,使用var/val声明的属性可通过对象直接访问,即是public修饰的,除非为属性声明private修饰符。
在Kotlin的世界里成员变量也可被子类复写。同方法的复写一样,需要在父类的成员属性前声明open表示可复写,子类声明override表示重写。
默认情况下属性在声明时必须赋值,除非把属性也声明为abstract的,类中有抽象属性时必须声明为抽象类。
非基本类型的不可空类型(val)的属性可延迟初始化赋值,使用 lateinit 实现该功能。只要保证在使用此属性时已赋值即可,若仍未赋值则会抛出属性尚未初始化异常。
若想避免上述异常可以在使用属性前使用isInitialized方法判断。
默认情况下每个属性都具有getter/setter方法
声明一个属性的完整语法如下:
属性初始值、getter/setter是可缺省,如果属性类型可以从初始值或getter中推断出来则也可缺省。val类型的属性不具备setter。
属性的getter/setter均可复写,即自定义访问器。如果我们定义了一个自定义的setter,那么每次给属性赋值时都会调用它。
来看一个例子:
打印结果:
这里需要解释一下,set方法声明的value是参数名,表示属性实际赋值时的那个对象,约定俗成写做value,可以随意写成其他。
field 指向当前属性,field标识符只能用在属性的访问器内。
若想控制setter访问,可以私有化setter。
kotlin(六):基本语法之返回跳转
kotlin与其他语言一样同样有三种跳出结构的方式
kotlin中任何表达式都可以用 lable{:.keyword} 标签来标记,label的格式是被 @ 标识符标记
如果有多重循环,带标签的break会跳转出标签所指示的那一个循环.带continue会调转到标签所指向的那个循环,进入该循环的下一次循环(常用语嵌套循环中)
先来介绍下test函数这个结构体,总的是一个for循环,里面还嵌套有一个for循环,都是从一到十循环,内外层每次循环都会打印一次,主要是内层循环里面的判断,我们来看下
当外层循环等于4时,会终止当前循环,后面跟有一个@l标识,与外层循环开头命名的l@相对应,总的意思就是会跳出当前循环,并进行下一次的循环,但是跳出的不是内部循环,而是外部循环,可以参考下打印的日志,在外部循环打印了 chuan:index 4 以及内部循环打印了chuan:j 1之后,因为触发了判断条件,所以直接跳出了外部循环的本次循环,直接开始了外部循环的第五次循环,也就是日志所打印的chuan: index 5
再来看第二个判断,如果外部循环等于5,并且内部循环等于3的时候,直接break了,后面依然跟着@l,我们来看下日志,发现中断了外部循环,也就是中断了所有的循环,直接打印了 chaun----循环完毕----
关于返回语句 return 没有什么太大的改动,但是kotlin中引入了内部函数,因此return如果在内部函数中使用的话,则会跳出内部函数,外部函数还是会继续的调用
Kotlin基础知识九: Generics
声明一个或多个形参(type parameters),例如class Map拥有K和V两个类型参数:class MapK, V。当一个实例被创建时,会使用特定的实参类型(type arguments)替换形参(type parameters)。
一般来说,实参类型可以由kotlin编译器推断而出,例如:
可以省去显式的类型声明(explicit type specification)。如果创建的是一个空的list,就无法推断出实参类型,因此需要显式的指定它:
与Java不同的是,Kotlin不支持原生类型(raw types),一个原生类型就是一个没有任何类型参数的泛型类,因此定义一个generic type时必须要指定形参类型(type arguments)。
fun关键字后面紧跟T表示声明类型为T的形参(Type parameter)。例如:
定义一个Kotlin的泛型类ListT如下:
其中尖括号括起来的T表示定义了一个形参类型(type parameter)T,然后T可以在class或interface中当成一个常规类型使用。
一个class可以把自身当做实参(type argument)。
例如:
String类实现了泛型的Comparable接口,并为形参类型T提供了String类型。
其中,T为Type parameter,T后面紧跟的分号加上Number表示upper bound。
对应的Java语法为:
看另外一个例子:
形参T的upper bound是一个泛型类型ComparableT。
当定义一个泛型类或函数时,实参类型可以是任何类型(包括Nullable)。没有指定约束的形参类型默认上界是Any?。
如果想指定一个non-null的类型约束,可以使用Any作为上界。
这时,ProcessorString?()会编译失败:
编译器在运行期(runtime)不会保留一个泛型类实例的实参类型(type arguments)。
与Java相同,Kotlin的Generics在运行时的类型是会被擦除的。也即一个Generic类的实例在运行期不会携带创建该实例时的实参类型(type arguments)。因此,对泛型类型实例使用is检验会导致编译失败(编译器已经已知的类型除外)。举例:
对generic function也是同理,在function body中无法确定被调用的实参类型(type argument)。举例:
如果把isA函数声明为inline、同时把形参声明为reified,那么这时候可以在运行期获悉被调用的是参类型。
另外一个例子是系统的filterIsInstance函数:
filterIsInstance函数的简单实现如下:
其中,reified关键字声明了实参类型(type argument)在运行期不会被擦除。