基本数值类型 Byte、Short、Int、Long、Float、Double 等。不同于 Java 的是,字符不属于数值类型,是一个独立的数据类型:
//基本数值类型包括 Byte、Short、Int、Long、Float、Double 等。不同于 Java 的是,字符不属于数值类型,是一个独立的数据类型
var byteValue: Byte = 123
var shortValue: Short = 123
var intValue: Int = 123
var longValue: Long = 123L
var floatValue: Float = 23.23f
var doubleValue: Double = 23.23
变量定义:
var name:String = "张三" //var 可变变量
val age:Int =18 //val 不可变变量,此时对age进行++或--都会报Val cannot be reassigned的错误
初始化变量为null的操作(添加?):
var name:String=null; //这样写会报Null can not be a value of a non-null type String的错误
var name:String? = null; //如果一定要写null,可这样写,添加一个?,意味着后续可以给变量赋值为null
//类型后面加?表示可为空
var age: String? = "23"
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1
//当一个引用可能为 null 值时, 对应的类型声明必须明确地标记为可为 null。
//当 str 中的字符串内容不是一个整数时, 返回 null:
fun parseInt(str: String): Int? {
// ...
}
条件判断:
val count: Int =18
var msg:String
//条件判断格式1:(if else模式)
if(count<18){
msg="你还是个少年"
}else if (count>=18&&count<30){
msg="你已经成年啦"
}else{
msg="你已经过了而立之年啦"
}
//条件判断格式2:(when模式)
var msg1:String = when {
count<18 -> "未成年"
count>=18&&count<30 -> "成年啦"
else -> "而立"
}
函数定义格式:
//函数的定义
fun getString(count:Int):String{
var msg1:String = when {
count<18 -> "未成年"
count>=18&&count<30 -> "成年啦"
else -> "而立"
}
return msg1
}
//调用函数
val msg = getString(count)
可变长参数vararg的使用:
/**
* vararg 可变长参数字段,用于可变长参数传递
*/
fun vars(vararg v: Int) {
for (vt in v) {
print(vt)
}
}
//调用
vars(1, 2, 3, 4, 5, 6, 7, 8, 9)
字符串模板使用:
/**
* 字符串模板
* $ 表示一个变量名或者变量值
* $varName 表示变量值
* ${varName.fun()} 表示变量的方法返回值
*/
fun strFom(str1:String,str2:String): String{
println("str1 is $str1 ,str2 is $str2")
return str1+str2
}
//调用
println("返回值是: ${strFom("hello ","world")}")
数值类型判断字符is,相当于java中的instanceof:
/**
* 类型判断字符is,相当于java中的instanceof
*/
fun objectType(obj : Any):String?{
when{
obj is String -> return "String"
obj is Int ->return "Int"
else -> return "other"
}
return null
}
//调用:
println("值类型是: ${objectType("hello")}")
for循环中的区间使用:区间 in 与 downTo ,步长step:
/**
* 区间 in 与 downTo ,步长step,
* 区间表达式由具有操作符形式 .. 的 rangeTo 函数辅以 in 和 !in 形成。
* 区间是为任何可比较类型定义的,但对于整型原生类型,它有一个优化的实现。
*/
fun testfun() {
//等同于 1 <= i && i <= 10,输出1到10
for (i in 1..10) {
println(i)
}
// 使用 step 指定步长
for (i in 1..4 step 2) {
println(i) // 输出“13”
}
//downTo,值从大到小
for (i in 4 downTo 1 step 2) {
println(i) // 输出“42”
}
// 使用 until 函数排除结束元素
for (i in 1 until 10) {
println(i) // i in [1, 10) 排除了 10
}
}
比较两个数字
Kotlin 中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针。数字类型也一样,所以在比较两个数字的时候,就有比较数据大小和比较两个对象是否相同的区别了。
在 Kotlin 中,三个等号 === 表示比较对象地址,两个 == 表示比较两个值大小。
val a: Int = 10000
println(a === a) // true,值相等,对象地址相等
//经过了装箱,创建了两个不同的对象
val boxedA: Int? = a
val anotherBoxedA: Int? = a
//虽然经过了装箱,但是值是相等的,都是10000
println(boxedA === anotherBoxedA) // false,值相等,对象地址不一样
println(boxedA == anotherBoxedA) // true,值相等
类型转换
由于不同的表示方式,较小类型并不是较大类型的子类型,较小的类型不能隐式转换为较大的类型。 这意味着在不进行显式转换的情况下我们不能把 Byte 型值赋给一个 Int 变量。
//每种数据类型都有下面的这些方法,可以转化为其它的类型:
//toByte(): Byte
//toShort(): Short
//toInt(): Int
//toLong(): Long
//toFloat(): Float
//toDouble(): Double
//toChar(): Char
val b: Byte = 1 // OK, 字面值是静态检测的
val i: Int = b.toInt() //
数组定义:
//类Array,还有ByteArray, ShortArray, IntArray,用来表示各个类型的数组,省去了装箱操作,因此效率更高,其用法同Array一样
var x: IntArray = intArrayOf(4, 2, 3)
for (value in x) {
println(value) //value是数组的具体值,输出4,2,3
}
for (i in x.indices) {
println(x[i]) //i是数组的下标,从0开始
}
字符串格式模板""" “”",由三个成对双引号包裹,输出字符串原有的格式排版:
val text = """
|多行字符串
|菜鸟教程
|多行字符串
|Runoob
"""
println(text)
//输出后的内容
|多行字符串
|菜鸟教程
|多行字符串
|Runoob
for循环控制:
for 循环可以对任何提供迭代器(iterator)的对象进行遍历
//对数组进行迭代
var x: IntArray = intArrayOf(4, 2, 3)
for (value in x) {
println(value) //value是数组的具体值,输出4,2,3
}
for (i in x.indices) {
println(x[i]) //i是数组的下标,从0开始
}
//对集合进行迭代
var items = listOf("张三","李四","王五")
for (value in items) {
println(value)
}
for (i in items.indices) {
println(items[i])
}
类
class Runoob { // 类名为 Runoob
// 大括号内是类体构成
}
类的成员变量:
类的属性可以用关键字 var 声明为可变的,否则使用只读关键字 val 声明为不可变。
class Runoob {
//必须初始化值
var name: String =""
var url: String =""
var city: String =""
}
类的构造器
Koltin 中的类可以有一个 主构造器,以及一个或多个次构造器,主构造器是类头部的一部分,位于类名称之后:
//constructor代表主构造器
class Person constructor(firstName: String) {}
如果主构造器没有任何注解,也没有任何可见度修饰符,那么constructor关键字可以省略。
class Person(firstName: String) {
}
实例:
class Person{
var name : String =""
get() = field.toUpperCase() // 将变量赋值后转换为大写
set
var no : Int =0
get() = field
set(value) {
if (value<10){ // 如果传入的值小于 10 返回该值
field = value
}else{ // 如果传入的值大于等于 10 返回 -1
field = -1
}
}
var heiht: Float = 145.4f
private set
}
调用:
var person: Person = Person()
person.name = "wang"
println("lastName:${person.name}")
person.no = 9
println("no:${person.no}")
person.no = 20
println("no:${person.no}")
//输出内容为:
//lastName:WANG
//no:9
//no:-1
主构造器
如果构造器有注解,或者有可见度修饰符,这时constructor关键字是必须的,注解和修饰符要放在它之前。
实例
创建一个 Runoob类,并通过构造函数传入网站名:
class Runoob constructor(name:String) {
// 大括号内是类体构成
var url: String = "http://www.runoob.com"
var country: String = "CN"
var siteName = name
init {
println("初始化网站名: ${name}")
}
fun printTest() {
println("我是类的函数")
}
}
//调用:
val runoob = Runoob("菜鸟教程")
println(runoob.siteName)
println(runoob.url)
println(runoob.country)
runoob.printTest()
…未完待续