Kotlin语法知识汇总

title: Kotlin语法
date: 2020-08-23 11:43
category: Kotlin
tags: Kotlin

基本数据类型

类型 位宽
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8

字面常量

常见的类型的字面量常量

  • 十进制: 124
  • 长整型以大写的L结尾: 123L
  • 16进制以0x开头:0x0F
  • 2进制以0b开头:0b0000001010
  • 注意:8进制不支持

Kotlin同时也支持传统符号表示的浮点数值

  • Doubles 默认写法: 123.4, 123.4e10
  • Floats 使用f或者F后缀:124.5f
val aa = 1_000_000
val cc = 1235_455_2224_55L
val ca = 999_22_1111L
val hexBytes = 0xFF_EC_DE_3F
val bytes = 0b10101001_10101_101011

比较两个数字

Kotlin中没有基础数据类型,只有封装的数字类型,定义的变量,Kotlin会将其封装成一个对象,

这样可以保证不会出现空指针.数字类型也一样,所以在比较两个数字的时候,就是比较两个数据的大小和地址是否相同.(equals, hashcode)

===表示比较对象地址,==表示比较两个值大小

fun main(arg:Array<String>){
   
    val a:Int = 1000
    println(a===a) // true 值相等,对象地址相等
    //经过装箱,创建了两个不同的对象
    val boxedA : Int? =a
    val autoBoxedA :Int? =a
    //经过了装箱(就是将基本数据类型包装成一个对象)
  	// 但是值是相等的
    println(boxedA == autoBoxedA) // true 值相等
    println(boxedA === autoBoxedA) //false 值相等,但是对象地址不一样
}

类型转换

由于不同的表示方式, 较小类型并不是较大类型的子类,较小类型不能隐式转换为较大的类型,这就意味着在不进行显示转换情况下.不能把Byte型值赋值给一个Int变量.

但是Java中不能将Int值赋值给一个Byte

  int b=1;
  byte a =(byte)b; // 较大类型的不能直接赋值给较小类型,区间范围不一致,只能通过将较大类型向下强转为较小类型


kotlin的规则:

val b : Byte =1 // ok,字面量是静态检测
val i : Int = b // 错误

//使用toInt方法来解决
val b:Byte=1 
val i:Int =b.toInt()

// 小的类型是不能直接赋值给大类型的Kotlin里面要求的,但是在Java中小类型是可以直接赋值给大类型数据
toByte():Byte
toShort():Short
toInt():Int
toLong():Long
toFloat():Float
toDouble():Double
toChar():Char

自动类型转化:

val l = 1L+3 //Long + Int = > Long

位操作符

对于Int和Long类型,还有相关的位操作法可以使用

shl(bits) -- >左移位(Java <<)
shr(bits) --->右移位(Java >>)
ushr(bits) ---> 无符号右移(Java >>>)
and(bits) - 与
or(bits) - 或
xor(bits) - 异或
inv() - 反向

字符

和Java不一样,Kotlin中的Char不能直接和数字操作,Char必须是单引号‘包含起来,比如普通的字符’0’,‘a’

fun check(c:Char){
   
    if(c==1){
    // 错误,类型不兼容
        
    }
}

数组

数组用类Array实现, 并且还有一个size属性以及get和set方法;

创建方式: 一种是使用函数arrayOf();另外一种是使用工厂函数

fun main(args:Array<String>){
   
    // [1,2,3]
    val a = arrayOf(1,2,3)
    //[0,2,4]
    val b = Array(3,{
   i->(i*2)})
    
   //读取数组内容
    println(a[0]) // 1
    println(b[2]) // 4
}

协变 与 逆变

Kotlin 中没有像Java一样的<? extends T>这样的方式, 也没有父类向子类的转换,但是为了数据的安全性,提出了协变与逆变的说法:

概念:

协变: A是B的子类型,并且Generic也是Generic的子类型,那么Generic可以被称之为一个协变类.

Java上界通配符<? extends T>

Java的协变通过上界通配符实现,如果Dog是Animal的子类,但是List并不是List的子类.

List<Animal> animals = new ArrayList<>();
List<Dog> dogs = new ArrayList<>();
animals = dogs; // 编译不通过

使用上界通配符之后,List<Dog>变成了List<? extends Animal>的子类型,即animals可以放入任何Animal以及子类的List;

List<? extends Animal> animals = new ArrayList<>();
List<Dog> dogs = new ArrayList<>();
animals = dogs; // 将Animal的子类型列表放入到animlas

Kotlin的关键字out

fun main(){
   
    var animals : List<Animal> = ArrayList()
    var dogs = ArrayList<Dog>()
    animals = dogs // why compile success
}

// Kotlin的List源码中使用了out,out相当于是Java上界通配符
public interface List<out E> : Collection<E> {
   

	//....
    override val size:Int
    
   	override fun contains(element:@UnsafeVariance E):Boolean
    
    override fun containsAll(elements:Collection<@UnsafeVariance E>):Boolean
    
}

类型的参数使用了out之后,该参数只能出现在方法的返回类型.

@UnsafeVariance修饰泛型E 打破了什么限制??

逆变: 如果A是B的子类型,并且Generic是Generic的子类型, 那么Generic可以被称之为逆变类

Java的逆变是通过下界通配符实现的,<? super T>

List<? extends Animal> animals = new ArrayList<>();
// 上界通配符 协变 是无法添加新的对象的. 编译器只能知道类型是Animal的子类,
// 并不能确定具体类型是什么,因此无法验证类型的安全性.
animals.add(new Dog()); // compile error

使用下界通配符之后,代码编译通过

List<? super Animal> animals = new ArrayList<>();
animals.add(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值