Kotlin——基础类型

时间:2021-6-12 作者:qvyue

Kotlin语言的类型

Kotlin语言与Java相同,也是一门强类型的语言:

  1. 所有的变量必须先声明后使用
  2. 指定类型的变量只能接受与之匹配的值

注释

Kotlin的注释与Java保持一致,Kotlin注释支持单行注释、多行注释和文档注释

单行注释和多行注释

  • 单行注释://
  • 多行注释:/包裹需要注释的代码/

Java语言的多行注释不支持嵌套,Kotlin语言的多行注释支持嵌套

文档注释

  • /** */ 表示文档注释

变量

分隔符

Kotlin语言中:分号(;)、花括号({})、方括号([])、圆括号(())、空格、圆点(.) 都具有特殊的分隔作用,因此被称为分隔符

分号 ;

Kotlin语言并不强制要求每条语句必须以分号结尾。但是也可以使用分号表示语句结束。如果单独一行内只有一条语句,那么Kotlin允许这条语句不以分号结尾。
但是如果打算在同一行内书写多条独立的语句,则前面语句需要使用分号表示结束。
Kotlin允许一条语句可以跨多行

var str = "fkit"
//表达式跨多行
str +=
      ”.org“
//方法调用跨多行
var hasFk = str
              .startWith("fk")
var st = "fkit"
//访问属性跨多行
var len = st
          .length

一个字符串、变量名不能跨多行

花括号

花括号的作用就是定义一个代码块。一个代码块值得就是{}中间包含的一段代码,代码块在逻辑上是一个整体。对于Kotlin而言,类体部分、枚举需要放在花括号中定义。方法体也必须放在花括号中定义

方括号

Kotlin的方括号是一个索引运算符,只要作用就是访问数组元素、List集合元素和Map集合元素。方括号通常紧跟数组变量名、List变量名或Map变量名,而方括号里指定希望访问的数组元素、List元素的索引或Map元素的key

Kotlin与Java不同的是,Java只有数组可以使用方括号表示索引

圆括号

圆括号是一个功能非常丰富的分隔符,在定义函数、方法时必须使用圆括号来包含所有的形参声明,在调用函数时也必须使用圆括号来传入实参值。圆括号还可以将表达式中某个部分括成一个整体,保证这个部分优先计算

空格

Kotlin语言使用空格分隔一条语句的不同部分。不可以使用空格把一个变量名隔开两个
除此外,Kotlin源程序还会使用空格合理地缩进代码

圆点

圆点通常作用类、结构体、枚举、实例和它的成员之间的分隔符,表名调用某个类或某个实例的指定成员。

标识符规则

标识符规则也称为命名规则:

  • 标识符的长度没有限制
    Kotlin语言区分大小写
  • 标识符由字符、数字、和下划线组成,不能以数字开头
    此处的字符不单单指26个英文字符,还可以包含中文字符,日文字符等
  • 标识符不能是Kotlin的硬关键字,但可以包含关键字
  • 标识符不能包含空格
  • 标识符只能包含下划线(_),不能包含@、#等特殊字符

Kotlin的关键字

  • 硬关键字:这些关键字无论在什么情况下都不能用作标识符
  • 软关键字:这些关键字可以在它们不起作用的上下文中用作标识符
  • 修饰符关键字:这些关键字可以在代码中用作标识符

声明变量

Kotlin是强类型的语言,Kotlin要求所有的变量必须先声明、后使用,声明变量时必须显式或隐式指定变量的类型,类型限制了一个变量能被赋的值,也限制了一个表达式可以产生的值,还限制了在这些值上可以进行的操作,并确定了这些操作的含义

  • 声明变量需要使用var或val
    • var声明的变量值是可变的,可被多次赋值的
    • val声明的变量是值不可变的,不可以被重新赋值
var|val 变量名[:类型][=初始值]

在声明变量时,要么通过:类型的形式显式指定该变量的类型,要么为该变量指定初始值——kotlin编译器将会根据该初始值确定变量的类型,不能声明变量时既不指定变量类型,也不指定变量初始值,声明变量时可以既显式指定变量类型,也指定该变量的初始值,显式指定的变量类型必须与初始值的类型保持一致

public fun main(args: Array) {
    //声明变量时显式指定类型
    var b : Int
    //声明变量时指定初始值,由编译器确定该变量的类型
    var name = "probuing"
    //为显式指定类型的变量赋值,类型必须一致
    b = 20
    name = "hello"
    //类型不一致 赋值错误
    name =12
    //声明变量显式指定类型与初始值类型一致
    var c: Int = 20
}

使用val声明的不可变变量相当于常量。其值一旦被初始化后,将不可以被重新赋值,根据常量所在位置不同,kotlin的常量分为两种

  • 局部范围的常量:这种常量允许在声明时不指定初始值,只要在第一次使用之前指定初始值即可
  • 类的常量属性: 这种常量属性既可以在声明时指定初始值,也可以在类或结构体的构造器中指定初始值
fun finalData() {
    //声明常量
    val maxAge = 100
    val name: String = "finalField"
    //局部范围常量 声明时不指定初始值
    val herName : String
}

整型

与Java类似,Kotlin也提供了4中整型

  • Byte:内存中占8位 表数范围 -128~127。兼容Java的byte和Byte类型

  • Short:内存中占16位,表数范围-2(15)~2(15)-1。兼容Java的Short和short类型

  • Int: int类型在内存中占32位 表数范围 -2(31)-1~2(31)-1,兼容Java的int和Integer类型

  • Long:Long型在内存中占64位,表数范围是-2(63)~2(63)-1,兼容Java的long和Long类型

Kotlin与Java不同,Kotlin的整型不是基本类型,而是引用类型,Byte、Short、Int、Long都继承了Number类型,因此他们都可以调用方法、访问属性
可以通过访问不同整数类型的MIN_VALUE和MAX_VALUE属性来获取对应类型的最大值和最小值

println(Short.MIN_VALUE)
println(Short.MAX_VALUE)

Kotlin是null安全的语言,Byte、Short、Int、Long型的变量都不能接受null值,如果要存储null值需要使用Byte?、Short?、Int?、Long?

fun nullSafety() {
    //Int类型无法接收 null 错误
    var notNull : Int = null
    //使用Int?类型可以接收null
    var nullAble : Int? = null
}

Kotlin允许在已有的数据类型后面添加”?”,添加”?”后的数据类型相当于对原有类型进行了扩展,带?的数据类型可支持被赋予null值

此外,整数类型添加”?”后缀与不加后缀还有一个区别——普通类型的整型变量将会映射成Java的基本类型;带?后缀的整型变量将会映射成基本类型的包装类

fun extendDataType() {
    //普通整型类型,将会被映射成java的基本数据类型
    var pm1: Int = 200
    var pm2: Int = 200
    println(pm1 === pm2)
    //带?的扩展类型将会映射成基本类型的包装类
    var ob1: Int? = 200
    var ob2: Int? = 200
    println(ob1 === ob2)
}

如果将ob1和ob2的值改为小于-128127之间的整数那么ob1和ob2用“===”比较依然是相等的,这是由Java的Integer类的特征决定的(Integer会对-128127的值静态缓存)
Kotlin的整数数值有3种表示方式:

  • 十进制
  • 二进制 以0b或0B开头的整数数值就是二进制的整数
  • 十六进制 以0x或0X开头的整数数值就是十六进制的整数
    kotlin不支持八进制整数

为了提高数值的可读性,Kotlin允许为数值(包括浮点型)增加下划线作为分隔符,也可以在数值前添加额外的零。这些下划线和零不会影响数值本身

fun underlineData(){
    var onMillon = 1_000_000
    val price = 234_234_234
    var android = 1234_1234_1234
    println(android)
}

浮点型

浮点型数值可以包含小数部分,浮点型比整型的表数范围更大,可以存储比Long型更大或更小的数,kotlin的浮点型分为两种

  • Float: 表示32位的浮点型
  • Double: 表示64位的双精度浮点型

Kotlin的浮点数的表示形式:

  1. 十进制数形式:5.23 0.5等
  2. 科学计数形式:512e2
    只有浮点数的数值才可以使用科学计数的形式表示,例如 51200是一个Int的值,但是512E2就是一个浮点型的值
  • 如果声明一个变量或常量时没有指定数据类型,只是简单地指定了其初始值为福电视,那么kotlin会自动判断该变量的类型为Double

特殊的浮点型

Kotlin还提供了3个特殊的浮点型数值:正无穷大、负无穷大和非数

  • 使用一个正数除以0.0将得到正无穷大的数值
  • 使用一个负数除以0.0将得到负无穷大的数值
  • 0.0除以0.0或是对负数开方将得到一个非数
  • 所有的正无穷大数值都相等,所有的负无穷大数值都相等,所有的非数不与任何数值相等,非数和自己也不相等

字符型

字符型通常用于表示单个的字符,字符型值必须使用单引号(‘)括起来
字符型的3中表示形式:

  • ‘A’ ’B‘
  • ’n‘ ‘t’
  • 使用Unicode值表示字符型值,’uXXX‘ 其中XXX表示十六进制的整数

与Java不同,Kotlin的Char型变量不能当成整数值使用,Char型变量或表达式不能赋值给整型变量,整型变量或表达式也不能赋值给Char型变量

数值型之间的类型转换

整型之间的转换

Kotlin不支持取值范围小的数据类型隐式转换为取值范围大的类型
Kotlin为所有的数值类型都提供了如下的方法进行数值类型转换:

  • toByte() 转换为Byte类型
  • toShort() 转换为Short类型
  • toInt() 转换为Int类型
  • toLong() 转换为Long类型
  • toFloat() 转换为Float类型
  • toDouble() 转换为Double类型
  • toChar() 转换为Char类型

Kotlin要求不同整型的变量或值之间必须进行显式转换

var bookPrice : Byte = 79
vae itemPrice : Short = 120
//错误类型转换
var a :Short = bookPrice
//正确类型转换
var a :Short = bookPrice.toShort()
var b: Byte = itemPrice.toByte()

在进行算术运算时,Kotlin并不需要对参与运算的数据进行强制转换,Kotlin将会自动把它们提升到Int类型之后再进行计算。整个表达式计算得到的结果是Int类型

浮点型与整型之间的转换

Kotlin的Float与Double之间需要进行显式转换,浮点型与整型之间也需要进行显式转换

表达式类型的自动提升

当一个算术表达式中包含多个数值型的值时,整个算术表达式的数据类型将发生自动提升

所有的Byte、Short将被提升到Int
整个算术表达式的数据类型自动提升到与表达式中最高等级操作数同样的类型
表达式的类型将严格保持和表达式中最高等级操作数相同,也就是说两个Int类型整数进行除法运算,即使无法除尽,也将得到一个Int类型结果

Boolean类型

布尔型只有一个Boolean类型,用于表示逻辑上的“真”或“假”,值只能是true或false。其他数据类型的值也不能转换成Boolean类型

null安全

null安全可以说是Kotlin语言对Java的重大改进之一。

非空类型和可空类型

//由于str转换为Int有可能失败,所以num有可能没有值,因此不能使用Int来声明num的类型
var num :Int = str.toIntOrNull()
var num:Int?=str.toIntOrNull()

Int:非空类型
Int?: 可空类型

Kotlin对可空类型进行了限制:不加任何处理,可空类型不允许直接调用方法、访问属性。因此,通过可空类型与非空类型的区分。Kotlin即可在程序中避免空指针异常

先判断后使用

由于可空类型的变量不允许直接调用方法或属性,但是可以先判断该变量不为Null,然后再调用该变量的方法或属性

    //定义可空对象
    var k: String? = "nullable obj"
    //先判断k是否为Null然后再调用方法
    var len = if(k!=null) k.length else -1

安全调用

例如如下代码

    var b: String? = "hello"
    println(b?.length)
    b = null
    println(b?.length)

上面程序中变量b类型是String?,因此程序使用了“?.”安全调用来访问b的length属性,而当b为Null时程序也不会引发NPE,而是返回null

Elvis运算

Elvis运算也是一种小技巧,其实就是简化了的if else 写法
先看如下代码

  //定义可空对象
    var k: String? = "nullable obj"
    //先判断k是否为Null然后再调用方法
    var len = if (k != null) k.length else -1
 var len2 = k?.length?:-1

上面程序中使用传统if else对k进行分支判断,当k不为null时返回k.length否则返回-1
len2使用“?.”运算符,该运算符就是Elvis——它的含义是:如果?.左边的表达式不为null则返回左边的表达式的值,否则返回?右边的表达式

强制调用

Kotlin使用!!可以强制调用可空变量的方法或属性

 var t : String? = "force"
    print(t!!.length)
    t = null
    print(t!!.length)//NPE

字符串

Kotlin使用String代表字符串,字符串表示一个有序的字符集合

字符串的类型

Kotlin字符串类型中的每一个字符都由独立的Unicode字符组成。String允许通过形如s[i]的格式来访问字符串指定索引处的字符。也可通过for循环遍历字符串中的每一个字符
Kotlin的字符串有两种字面值

  • 转义字符串:转义字符串可以有转义字符
  • 原始字符串:原始字符串可以包含换行和任意文本,原始字符串需要使用3个引号引起来
  //普通字符串
    var nomalStr:String = "it's originString"
    //原始字符串
    var originStr:String = """it's origin String sfdfsdfs 
        |test1
    """;
    println(nomalStr)
    println(originStr)

我们一般在写代码的时候考虑到程序的格式,往往会在原始字符串中进行一些缩进,但是这些缩进并不是原始字符串中希望包含的,此时可以使用trimMargin()来去掉原始字符串前面的缩进——在默认情况下,Kotlin使用竖线|作为边界符,也就是说,所有竖线之前的内容都会被去掉。
也可以使用其他字符作为边界符,此时就需要在trimMargin()方法中传入该边界符作为参数

 var frontierStr:String = """
                ^这是一个自己定义的原始字符串
                ^这个字符串是用自定义边界符分隔
                ^测试一下吧
                $ 
    """.trimMargin("^")
    println(frontierStr

字符串模板

Kotlin允许在字符串中嵌入变量或表达式,只要将变量或表达式放入${}中即可,这样Kotlin将会把该变量或表达式的值嵌入该字符串中
字符串模板不仅可以在普通字符串中使用,也可以在原始字符串中使用

  val bookPrice : Int = 79
    //在字符串模板中嵌入变量
    print("图书的价格是${bookPrice}")
    //字符串模板中嵌入方法调用
    var rand = Random()
    println("下一个随机数是${rand.nextInt(10)}")

Kotlin字符串的方法

Kotlin的String 与Java的String并不是同一个类。因此它们的方法略有不同,但是这两个类所提供的功能大致相似

  • toXxx() 将字符串转换成数值
 //toXxx将字符串转换为数值
    val s1 = "2.741"
    //toDouble 将String转换为Double
    var b: Double = s1.toDouble()
    //toInt 将字符串转为Int
    val si = "23"
    var i: Int = si.toInt()
    
  • 首字母大写/小写
  //转换大小写
    val  s1 = "hello"
    val  s2 = "Hello"

    //首字母大写
    println(s1.capitalize())
    //首字母小写
    println(s2.decapitalize())
  • 返回两个字符串相同的前缀/后缀

    var samePrefix = "www.baidu.com"
    //返回两个字符串相同的前缀
    println(samePrefix.commonPrefixWith("www"))
    //返回两个字符串相同的后缀
    println(samePrefix.commonSuffixWith("www.sina.com"))

类型别名

Kotlin提供了类似于C语言中的typedef功能:可以为已有的类型指定另一个可读性更强的名字,Kotlin提供了typealias来定义类型别名

typealias 类型别名 = 已有类型

通常可以缩短一些名称很长的类

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。