Kotlin数据类型
在Kotlin之中,没有所谓的基本数据类型.也就是说可以将Kotlin的数据全部理解成java之中的对象.
但是Kotlin定义了基本数值类型和java是一样的Byte,Short,Int,Long,Float,Double等
以上的数据也只是Kotlin默认封装的值.和我们自己定义的类没有区别
类型 | 字节 |
---|---|
Int | 32 |
Short | 16 |
Byte | 8 |
Float | 32 |
Double | 64 |
Long | 64 |
注意
long以大写的L结尾: 123L
16进制以0x开头: 0x0F
2进制以0b开头: 0b00001011
传统符号表示的浮点数值
Doubles 写法:123.5e10
Floats 使用F或者f结尾: 123.5f 实例:
代码语言:javascript复制 var s :Long = 123L
var s1:Float=123f
var s2:Double=123e10
var s3:Double=123.4
println(s2)
println(s3)
Kotlin基本语法与数据类型
介绍: Kotlin文件都是以.kt作为后缀名.
包结构
代码语言:javascript复制package cn.demo.test1
函数定义
代码语言:javascript复制fun test(a:Int,b:String,c:Char,d:Float,r:Double,f:Array<String>)):Int{
//当前函数的名称叫做test, 返回值为Int,传值a,b,c,d,r,f;
return 0;
}
//没有返回值
fun test1(a:Int){
}
//可变数组传参
fun test2(vararg v: Int){
for (v1 in v) {
print(v1);
}
}
介绍: 函数定义使用关键字 fun,参数格式为:参数 : 类型
相较于java, kotlin的函数有fun关键字进行标注,其次函数的传参是参数在类型的前面.
具体的传参类型和java是一样的.
还有一个区别在于,返回值,写在了函数的最后.
常量与变量
介绍: 通过var关键字定义可变变量
通过val 关键字定义不可变变量.类似于java之中的final修饰符.赋值后不能修改.
格式:
代码语言:javascript复制var <变量名>:<类型> =<初始化值>
val <变量名>:<类型> =<初始化值>
特性 Kotlin 支持自动类型判断,也就是说在创建时可以不指定类型.赋值后编译器会自动判断类型;
代码语言:javascript复制//定义常量, 类似final 修饰符定义的数据
val a =1;
val b:Int =1;
var c ="string";
//上面是直接赋值了,所以可以省略类型定义.如果没有赋值需要定义类型.
var e : String
字符串模板
可以参考在java 之中String 字段的%d等替换值.
在kotlin之中$
表达一个变量名或者变量值.
$varName 表达变量值
${varName.fun()}表达变量方法的返回值;
实例
代码语言:javascript复制fun main(args: Array<String>) {
//定义一个int 变量 参数1
var a =1;
//定义了一个字符串
var str ="a is $a";
//打印字符串
println(str);
}
输出结果:
代码语言:javascript复制a is 1
实例2
代码语言:javascript复制fun main(args: Array<String>) {
//定义一个int 变量 参数1
var a =1;
//定义了一个字符串
var s1 ="a is $a";
//打印字符串
a=12;
println(s1);
//将s1字符串之中的is 替换为was
var s2 = "${s1.replace("is","was")},but now is $a"
println(s2);
}
输出:
代码语言:javascript复制a is 1
a was 1,but now is 12
通过这两个例子应该能够理解字符串模板的意义了.
NULL 空值定义和检查机制
通过在名称后面添加!!
,来告诉编译器要检测NULL.如果出现NULL 抛空值异常.
实例:
代码语言:javascript复制fun main(args: Array<String>) {
var age:String?=null;
val ages = age!!.toInt();
}
输出结果:
代码语言:javascript复制Exception in thread "main" java.lang.NullPointerException
at cn.demo.key.DemoKt.main(Demo.kt:45)
Process finished with exit code 1
类型后面添加?
可以不做处理,返回值为null或者配合?:
做空判断处理
文字介绍不够清晰,实例会明白什么意思.
实例:
代码语言:javascript复制 var age:String?=null; //不添加上?无法给该值赋值为null
// val ages = age!!.toInt();
val ages1 = age?.toInt();
println(ages1);
输出:
代码语言:javascript复制null
理解: 添加了? 就是告诉编译器,该值我不确定是否有值.所以可以输入null,也可以输入具体参数值.
空值判断
实例:
代码语言:javascript复制fun main(args: Array<String>) {
var age: String?=null
val t1 = age?.toInt()
println(t1)
//得到age的值并转为Int,如果是空的话,返回-1; 可以作为判空处理逻辑
val t2 = age?.toInt() ?:-1
println(t2);
}
输出:
代码语言:javascript复制null
-1
函数值返回NULL 定义
如果一个函数的参数,不能确定一定有值,可能返回Null的情况下.在返回值类型后面添加?
实例:
函数test7 的返回值是一个Int ,但是我可以直接写返回Null. 因为我在Int后面添加有?号标注.
告诉了编译器,这个函数的返回值可以有null.
代码语言:javascript复制 fun test7(s: String): Int? {
if (s == "a") {
return 1
}
return null
}
fun main(args: Array<String>) {
var ss = test7("a")
var tt = test7("a")
//下面这行代码会报错, 主要因为使用了乘法运行,但是ss 和tt的值可能为NUll.
println(ss * tt);
//所以需要进行空值判断后才能进行运行.
if (ss != null && tt != null) {
println(ss * tt);
}
//还有一种写法, 如果出现null值就用1代替.也可以减少if的判断
ss = test7("a")?:1
tt = test7("a")?:1
println(ss * tt);
}
类型判断
在kotlin之中,使用is
运算符来达到java之中的instanceof
字符的效果.判断数据是什么类型
实例:
代码语言:javascript复制 fun getStringLength(obj:Any?):Int?{
if(obj is String){
return obj.length;
}
if(obj is Int){
return obj
}
return -1;
}
fun main(args: Array<String>) {
var test = getStringLength("asd");
var test1 =getStringLength(1231);
var test2 =getStringLength(null);
println(test);
println(test1);
println(test2);
}
输出:
代码语言:javascript复制3
1231
-1
区间
介绍:主要是由..
符号表示. 是为任何可比较类型定义的
估计更多的使用在整型数据类型之中了.
也可以将区间理解为范围
实例1:
代码语言:javascript复制package cn.zinyan.key
class Demo() {
//带返回值和传参的函数 ,返回值为Int
fun test1(a: Int, f: Array<String>): Int {
return a
}
//带返回值和传参的函数 ,返回值为String
fun test2(a: Int, b: Int): String {
return "返回值"
}
//带可变数组传参可以参考java之中的...定义, 返回值为vold
fun test3(vararg v: Int) {
for (v1 in v) {
print(v1)
}
println("结束")
}
//lambda 匿名函数表达方式 . 可以专门学习Lambda
fun test4() {
val sumLambda: (Int, Int) -> Int = { x, y -> x y }
println("test4:输出结果" sumLambda(1, 2)) //输出结果为3
}
//字符串替换模板
fun test5() {
//定义一个int 变量 参数1
var a = 1;
//定义了一个字符串
var s1 = "a is $a";
//打印字符串
a = 12;
println(s1);
var s2 = "${s1.replace("is", "was")},but now is $a"
println(s2);
}
fun test6() {
var age: String? = null
val t1 = age?.toInt()
println(t1)
//得到age的值并转为Int,如果是空的话,返回-1; 可以作为判空处理逻辑
val t2 = age?.toInt() ?: -1
println(t2);
}
fun test7(s: String): Int? {
if (s == "a") {
return 1
}
return null
}
fun test8() {
var ss = test7("a") ?: 1
var tt = test7("a") ?: 1
println(ss * tt);
// if (ss != null && tt != null) {
// println(ss * tt);
// }
}
// obj对象可以用Any 关键字定义数据类型
fun getStringLength(obj: Any?): Int? {
//is 类型值判断
if (obj is String) {
return obj.length;
}
if (obj is Int) {
return obj
}
return -1;
}
//is 类型值判断
fun test9() {
var test = getStringLength("asd");
var test1 = getStringLength(1231);
var test2 = getStringLength(null);
println(test);
println(test1);
println(test2);
}
}
fun main(args: Array<String>) {
//定义一个1到10的区间数, 还有CharRange,LongRange的区间
var range1:IntRange=1..10
var range2:IntRange=4..1
println("输出区间range1");
for (i in range1) print(i)
//没有输出
println("n输出区间range2");
for (i in range2) print(i)
//如果是重大到小使用downTo
println();
println("从大到小的写法")
for (i in 10 downTo 1) print(i)
println();
//step 表示间隔长度. 步长
for (i in 10 downTo 1 step 2) print(i)
println();
println("按照步长3进行打印")
for( i in range1 step 3) print(i)
println();
println("使用until函数排除元素")
for(i in 1 until 5 ){ //用数学式表示:"[1,5)" 当i
print(i)
}
}
输出:
代码语言:javascript复制输出区间range1
12345678910
输出区间range2
从大到小的写法
10987654321
108642
按照步长3进行打印
14710
使用until函数排除元素
13
区间介绍,顺便也介绍了for循环的使用
数值设置
在kotlin之中,定义的数值可以使用_
来进行分割,而不影响数值比较
实例:
代码语言:javascript复制 var s = 123_1111_2222_222
var ss = 12311112222222
println(s)
if(ss==s)
print("两个数相等")
输出:
代码语言:javascript复制12311112222222
两个数相等
这样可以方便阅读数值
比较 "==" 和"==="
介绍:在Kotlin之中没有基础数据类型,只有封装对象.
在Kotlin之中 ===
表示比较两个对象的内存地址.
==
表示比较两个值得大小.
实例:
代码语言:javascript复制 var a: Int = 100000
print("三个等号 自身比较:")
println(a===a) //true, 相同对象内存地址相等
var A:Int =a
var B:Int =a
print("经过赋值之后 三个等号比较两个box对象:")
println(A===B)
print("经过赋值之后 两个等号比较两个box对象:")
println(A==B)
println("A:$A,B:$B")
a=500
println("A:$A,B:$B")
var boxA:Int? =a
var boxB:Int? =a
print("经过赋值之后 三个等号比较两个box对象:")
println(boxA===boxB)
print("经过赋值之后 两个等号比较两个box对象:")
println(boxA==boxB)
输出:
代码语言:javascript复制三个等号 自身比较:true
经过赋值之后 三个等号比较两个box对象:true
经过赋值之后 两个等号比较两个box对象:true
A:100000,B:100000
A:100000,B:100000
经过赋值之后 三个等号比较两个box对象:false
经过赋值之后 两个等号比较两个box对象:true
注意:
请注意=
与?=
的赋值区别.
类型转换
介绍: 由于没有基础类型, 全是封装的独立对象.所以在Kotlin之中,不能隐式转换. Kotlin之中不支持这种直接转换.
实例:
代码语言:javascript复制 var v:Int = 1
var i:Long =v //错误
var i:Long = v.toLong() //正确的写法
在Kotlin之中,所有的数据类型都有下面的这几种转换方法
代码语言:javascript复制toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
但是在某些情况下,也支持自动类型转换.
前提条件是编译器能够根据上下文计算环境推断出正确的数据类型
例如:
代码语言:javascript复制val l = 1L 3 // Long Int => Long
位操作符
介绍:Kotlin之中也有java之中的<< ,>>位操作符
代码语言:javascript复制shl(bits) – 左移位 (Java’s <<)
shr(bits) – 右移位 (Java’s >>)
ushr(bits) – 无符号右移位 (Java’s >>>)
and(bits) – 与
or(bits) – 或
xor(bits) – 异或
inv() – 反向
数组
在Kotlin之中数组使用Array实现。
数组的创建有两种方式:
1.使用函数arrayOf():
2.使用工厂函数:
实例:
代码语言:javascript复制fun main(args: Array<String>) {
//使用arrayOf()创建了一个数组,[1,2,3]
val a = arrayOf(1, 2, 3)
//工厂函数,创建了一个数组, 数组长度3. 然后数组数据的增长方式为 每次*2
//结果为[0,2,4,6]
val b = Array(4, { i -> (i * 2) })
//输出数组
for(v1 in b){
println(v1)
}
}
输出:
代码语言:javascript复制0
2
4
6
除了Array 外,还有ByteArray,ShortArray,IntArray 等用来表示各种类型的数组
实例:
代码语言:javascript复制//复习:val 定义常量, var 定义变量
val x: IntArray = intArrayOf(1, 2, 3, 4, 5, 6, 6, 7, 8)
x[0] = x[1] x[2] x[3]
println(x[0])
//输出结果为 9
字符串
介绍:Kotlin之中可以通过[] 语法获取字符串中的某个字符。也能够通过for来循环遍历
可以将字符串理解成特殊的Array。
代码语言:javascript复制fun main(args: Array<String>) {
var str: String = "这是一个字符串"
for (c in str) {
println(c)
}
}
输出:
代码语言:javascript复制这
是
一
个
字
符
串
同时,Kotlin 支持三个引号创建的多行字符串
例如:
代码语言:javascript复制var str1 ="""
白日依山尽
黄河入海流
"""
println(str1)
输出:
代码语言:javascript复制 白日依山尽
黄河入海流
这会有多余的空白。我们可以通过trimMargin()方法配合“|” 来处理 “|”定义了需要删除的边缘。效果
代码语言:javascript复制var str1 ="""
|白日依山尽
|黄河入海流
""".trimMargin()
println(str1)
输出:
代码语言:javascript复制白日依山尽
黄河入海流
默认是使用“|”来处理,如果字符串之中有其他字符相同了。你可以定义其他字符来作为边界定义。
方法:trimMargin(">")