Koltin 基础类型(一)

基本数据类型

在Kotlin中所有东西都是对象,包括数字,布尔,字符串等,但是它们在运行时可以表示为原生类型值。

数字

Kotlin中的数字没有隐式拓宽。Double参数的值只能对Double值调用,不能对Float,Int调用。如果想要将数值转化为不同的类型,需要使用显示转换。
整数类型
类型大小 (字节)bit
Byte18
Short216
Int432
Long864

Tips:未超出Int最大值的整型会被推断为Int,超过的则会被推断为Long。显示指定Long类型值,可以在值后面追加L。

    val b:Byte=12
    val s:Short=20
    val i=1000
    val l=200003203203203202
    val lL=20L
    val c:Double=b.toDouble()
    println(b.javaClass.simpleName)//byte
    println(s.javaClass.simpleName)//short
    println(lL.javaClass.simpleName)//long
    println(c.javaClass.simpleName)//double
浮点类型
类型大小(字节)bit十进制位数
Float4326~7
Double86415~16

Tips:
1.对于浮点类型,编译器默认推断为Double类型。
2.显示指定为Float类型,可以在值后面添加f后者F。
3.如果显示指定为Float类型,其十进制位数超过6~7,那么其后面多余的位数将被舍弃。

字面常量

Koltin不支持八进制。

十进制:123, Long类型:123L
十六进制:0x0F
二进制:0b00001011

浮点数表示:
默认Double:123.5,123.5e10
Float:123.5f,123.5F。

添加下划线(_)是数字更加易读

val a=1_000_000
val b=0x_12_AC_BC
Jvm平台的数字表示

Jvm平台数字存储为原生类型int,double等类型。
Int?(可空类型)或使用泛型,在这些场景下数字会自动装箱为Integer,Double类型。

    val a=20
    val b:Int?=a
    val c=130
    val d:Int?=c
    //引用比较
    println(a===b)//true
    println(c===d)//false
    //值比较
    println(a==b)//true
    println(c==d)//true

Jvm会对-128到127的整数进行内存优化,所以a,b其实指向的是同一个对象。c,d因为已经超出了127所以没有优化,是不同的对象。

显示转换

较小的类型并不是较大类型的子类,所以把一个类型赋值给另一个类型需要显示转换。

    val a:Int=20
	val b:Long=a //报错
    val c:Long=a.toLong()//显示转换
自动推断

有些时候不需要显示转换,类型会从上下文中推断出来,算术运算符会有重载做适当转换。

    val a:Int=20
    val b=10L+a
    println(b is Long) //true
运算

Koltin支持标准的运算符集:+,-,*,,%,并支持运算符重载。

整数除法

整数间的除法总是返回整数,会丢弃小数部分。如果需要返回浮点类型,可以将其中任何一个显示转换为浮点类型。

位运算

只针对整数类型,可以通过中缀形式调用的函数表示,只能作用于Int,Long。

运算说明
shl(bits)有符号做移
shr(bits)有符号右移
ushr(bits)无符号右移
and(bits)
or(bits)
xor(bits)异或
inv()

Q:为什么Java和Kotlin中没有无符号左移?
A:因为左移是在后面补0,而右移是在前面补1或0,有无符号是取决于数的前面第一位是1还是0,所以右移会产生在前面补1或0的问题,而左移始终是往后面补0,不存在符号的问题,所以没有必要无符号左移。

    val b:Byte=1
    val s:Short=2
    val i: Int = 3
    val l:Long=4L
    val s1=b shl 2 // 报错
    val s2=s shl 2 // 报错
    val s3=i shl 2 
    val s4=l shl 2
浮点数比较

相等性检测:a==b,a!=b
比较操作符:a>b,a<b,a>=b,a<=b
区间实例以及区间检测:a…b,x in a…b,x !in a…b

无符号整型
类型大小(字节)范围
UByte10到255
UShort20 到65535
UInt40 到 2^32 - 1
ULong80 到 2^64 - 1

UByteArray:无符号字节数组
UShortArray:无符号短整型数组
UIntArray:无符号整型数组
ULongArray:无符号长整型数组

字面值

u与U将字面值标记为无符号。
uL与UL将字面值标记为无符号长整型。

布尔

Kotlin中布尔位Boolean类型,可定义为可空类型Boolean?。

字符

用Char表示,字符字面值用单引号括起。
特殊字符可以使用转义反斜杠\。
编码其它字符需要使用Unicode转义序列语法:‘\uFF00’

val chr:Char='a'
val unicode:Char='\uFF00'

字符串

用String表示,是不可变的。可以使用索引来访问字符串的元素-字符。

    val str = "Hello World"
    val firstChar=str[0]
    val lastChar=str[str.lastIndex]
    println(firstChar) // H
    println(lastChar) // d

字符串链接可以使用:+操作符,也用于连接字符串与其它类型数据,只要表达式中的第一个元素是字符串即可。
Tips;大多数情况下推荐使用字符串模版或者原始字符串。

   val h = "Hello"
   val w="World"
   println(h+w) //"HelloWorld"
   val a:Int =2
   println(h+a) // "Hello2
字符串字面值

转义字符串:可以包含转义字符。
原始字符串:可以包含换行及任意文本。

    val str = "Hello \n World"
    val str1 = """|Hello
        |World
        |str1
    """.trimMargin()//默认使用|作为边界前缀,可自定义,例如:用">",.trimMargin(">")。
    println(str)
    println(str1)
    输出结果:
	Hello 
	 World
	Hello
	World
	str1
字符串模版

字符串字⾯值可以包含模板表达式——⼀些⼩段代码,会求值并把结果合并到字符串
中。 模板表达式以美元符( $ )开头。用两种形式:$a, ${a}

    val a=20
    val b=20
    val str = "Hello World $a"
    val str1 = "a+b=${a+b}"
    println(str) // Hello World 20
    println(str1) // a+b=40

数组

用Array表示,定义了get与set函数(按照重载运算符约定会变为[])以及size属性和其它有用函数。
Kotlin中的数组是不型变的,所以Array<String>并不能赋值给Array<Any>。
创建
非原生类型数组,会有装箱开销。
arrayOf(vararg  elements:T)  
arrayOfNulls(size:Int)
Array(size: Int, init: (Int) -> T)
    val arr = arrayOf(1, 2, 3, 4, 5, 6)
    val arr1 = arrayOfNulls<Int>(5)
    val arr2 = Array(5) {
        it*2
    }
    println(arr.contentToString())
    println(arr1.contentToString())
    println(arr2.contentToString())
    输出结果:
    [1, 2, 3, 4, 5, 6]
	[null, null, null, null, null]	
	[0, 2, 4, 6, 8]
原生类型数组,无装箱开销

ByteArray,ShortArray,IntArray等等,这些类与Array并没有继承关系。
构建方法:
byteArrayOf,shortArrayOf,intArrayOf等等工厂方法来提供构建能力。
IntArray(size: Int)
IntArray(size: Int, init: (Int) -> Int)

    //非原生数组类型Array与原生类型数组IntArray对比
    val arr= arrayOf(1,2,3)
    val arr1= intArrayOf(1,2,3)
    反编译后的Java代码
    Integer[] var10000 = new Integer[]{1, 2, 3};
    int[] var2 = new int[]{1, 2, 3};

类型检测与类型转换

is,!is在运行时可以检测对象是否是指令类型。

智能转换

大多数情况下,在使用is操作符以后,会自动把对象转换为目标类型。

请注意,当编译器能保证变量在检测和使⽤之间不可改变时,智能转换才有效。 更具体
地,智能转换适⽤于以下情形:
val 局部变量——总是可以,局部委托属性除外。
val 属性——如果属性是 private 或 internal,或者该检测在声明属性的同⼀模块
中执⾏。智能转换不能⽤于 open 的属性或者具有⾃定义 getter 的属性。
var 局部变量——如果变量在检测和使⽤之间没有修改、没有在会修改它的
lambda 中捕获、并且不是局部委托属性。
var 属性——决不可能(因为该变量可以随时被其他代码修改)。

转换操作符 as 不安全的

转换失败会跑出异常。
Tips:null不能转换为不可空类型,必须说可空类型才可以。

转换操作符 as? 安全的

转换失败不会抛出异常,会返回null。

类型擦除与泛型检测 <待补充>

泛型类型擦除后编译器禁止运行时使用is类型检测,但是可以对非泛型部分检测。

非受检类型转换 <待补充>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值