# kotlin入门
# 基本类型
# 概述
数字(Byte,Short,Int,Long; Float,Double)
无符号整数(Ubyte,Ushort,Uint,Ulong)
布尔(Boolean,true,false)
字符(Char)
字符串(String)
数组(Array)
类型 | 位宽度 | 说明 |
---|---|---|
Byte | 8 | 整数类型 |
Short | 16 | 整数类型 |
Int | 32 | 整数类型 |
Long | 64 | 整数类型 |
Float | 32 | 浮点数类型 |
Double | 64 | 浮点数类型 |
Char | ‘a’ | 字符型,用单引号表示,不属于数值类型,不能直接与整型参与运算 |
Boolean | true/false | 布尔型 |
String | "abc" | 字符串 |
Array | [] | 数组 |
Ubyte | 8 | 无符号整数类型 |
Ushort | 16 | 无符号整数类型 |
Uint | 32 | 无符号整数类型 |
ULong | 64 | 无符号整数类型 |
# 数字
# 整数类型
Byte
Short
Int:默认
Long
类型 | 位宽 | 值范围 |
---|---|---|
Byte | 8 | -128(-2的7次方)~127(2的7次方减1) |
Short | 16 | -32768(-2的15次方)~32767(2的15次方减1) |
Int | 32 | -2,147,483,648(-2的31次方)~2,147,483,647(2的31次方减1) |
Long | 64 | -9,223,372,036,854,775,808(-2的63次方)~9,223,372,036,854,775,807(2的63次方减1) |
/**
* 整数的定义
* 默认会自动推断为Int类型,当值超出Int范围时会自动推断为Long型。
* 也可以显式指定类型
* Long型可以用L后缀指定
*/
val one = 1 // Int
val threeBillion = 3_000_000_000 // Long
val oneSuffixL = 1L // Long
val oneByte: Byte = 1 // Byte
val oneShort: Short = 1 // Short
val oneInt: Int = 1 // Int,Int可省略
val oneLong: Long = 1 // Long
# 浮点类型
- Float 指定f/F
- Double 默认
类型 | 位宽 | 整数位 | 指数位 | 小数位 |
---|---|---|---|---|
Float | 32 | 24 | 8 | 6-7 |
Double | 64 | 53 | 11 | 15-16 |
/**
* 浮点数的定义,必须带点.
* 超过精度会被截断,精度不准
*
*/
val onePointZeroDouble = 1.0 //Double
val onePointZerof = 1.0f
val onePointZeroF = 1.0F
println("onePointZero type is ${onePointZeroDouble.javaClass.name}, value is $onePointZeroDouble")
println("onePointZerof type is ${onePointZerof.javaClass.name}, value is $onePointZerof")
println("onePointZeroF type is ${onePointZeroF.javaClass.name}, value is $onePointZeroF")
// val one: Float = 1 //Error
# 数字的文字常量
- 不支持八进制
- 二进制用
0b
开头- 十六进制用
0x
开头- Long型由
L
结尾- Float型由
f/F
结尾- 支持指数(e/E)表示方式
- 可以添加下划线增强可读性
- 数字(默认Int):
123
,12345
- Long型:
123L
- 二进制:
0b0010
,0b11
,0b1101
- Double型(默认):
123.0
,123.4e13
,123.4E13
- Float型:
123.0f
,123.0F
,1.1236e7
,1.125E5
//支持指数格式
val exponent = 1.1234e5
println(exponent) // 112340.0
val exponent2 = 1.123477E5
println(exponent2) // 112347.7
//下划线
val underscores2 = 1_000_000
val underscores1 = 999_99_222L
val hexBytes = 0xFF_ED_23
val bytes = 0b0101_0101_1100
# JVM上的数字表示形式
- 两个等号比较值(等同Java的equal),三个等号比较引用(对象地址,等同Java的==)。
- nullable引用的值在
-128~127
之间,值相等时,引用也相等(由于JVM的内存优化)- nullable引用的值在
-128~127
以外,值相等时,引用不相等。- 数值装箱原则造成的影响。
- 字符,字符串等的比较三个等号与三个等号结果都一致
fun main(args: Array<String>){
val i1Plus127: Int? = 127
val i2Plus127: Int? = 127
println("i1Plus127 == i2Plus127 is ${ i1Plus127 == i2Plus127}") //true,比较值。
println("i1Plus127 === i2Plus127 is ${ i1Plus127 === i2Plus127}") //true,比较对象地址,127永远指向同一个对象
val i3Plus128: Int? = 128
val i4Plus128: Int? = 128
println("i3Plus128 == i4Plus128 is ${ i3Plus128 == i4Plus128}") //true, 比较值。
println("i3Plus128 === i4Plus128 is ${ i3Plus128 === i4Plus128}") //false, 比较对象地址,大于127的值指向不同对象
val i5Minus128: Int? = -128
val i6Minus128: Int? = -128
println("i5Minus128 == i6Minus128 is ${ i5Minus128 == i6Minus128}") //true,
println("i5Minus128 === i6Minus128 is ${ i5Minus128 === i6Minus128}") //true
val i7Minus129: Int? = -129
val i8Minus129: Int? = -129
println("i7Minus129 == i8Minus129 is ${ i7Minus129 == i8Minus129}") //true
println("i7Minus129 === i8Minus129 is ${ i7Minus129 === i8Minus129}") //false
val a1: Char? = 'a'
val a2: Char? = 'a'
println("a1 == a2 is ${a1 == a2}") // true
println("a1 === a2 is ${a1 === a2}") // true
val s1: String? = "ab"
val s2: String? = "ab"
println("s1 == s2 is ${s1 == s2}") // true
println("s1 === s2 is ${s1 === s2}") // true
val bl1: Boolean? = true
val bl2: Boolean? = true
println("bl1 == bl2 is ${bl1 == bl2}") // true
println("bl1 === bl2 is ${bl1 === bl2}") // true
}
# 显式数字类型转换
- 数字类型之间不会自动类型转换(与Java不同)
- 变量需要显式进行类型转换
- 运算表达式中当可通过上下文推断类型时就不需要显式转换
toByte():Byte
toShort():Short
toInt():Int
toLong():Long
toFloat():Float
toDouble():Double
/**
* @Description 显式数字转换
* @Author 刘默远
* @Email soul.lau0328@gmail.com
* @Date 2023/10/10 10:37
*/
fun main(args: Array<String>) {
integerConversions()
floatConversions()
}
fun integerConversions() {
val b: Byte? = 10
val s = b?.toShort()
val i = b?.toInt()
val l = b?.toLong()
val b1 = b?.toByte()
println("$b:$s:$i:$l:$b1")
}
fun floatConversions() {
val f: Float? = 10F
val d = f?.toDouble()
val f1 = d?.toFloat()
println("$f:$d:$f1")
}
# 数字的运算
- 支持的运算符号:加
+
, 减-
, 乘*
, 除/
, 求余%
# 整数的除法
- 整数的除法只返回整数部分结果,丢弃小数部分
- 整数相除,要保留小数,则需要显式把基中一个参数转换为浮点类型
- 与Java等同。
/**
* 除法
*/
fun division() {
val a = 13
val b = 4
val c = a / b
println(c) // 3
val d = a / b.toDouble() //
println(d) // 3.25
}
# 按位运算
- 只能作用于
Int
和Long
- 支持表达式写法(
inv
除外)和函数式写法
shl(bits)
- 有符号左移,每移一位等价*2,signed shift leftshr(bits)
- 有符号右移,每移一位等价/2,signed shift rightuhr(bits)
- 无符号右移,每移一位等价/2,unsigned shift rightand(bits)
- 按位与,bitwise ANDor(bits)
- 按位或,bitwise ORxor(bits)
- 按位异或,bitwise XORinv()
- 按位反转,即+1取反 bitwise inversion
/**
* 按位运算
*/
fun bitwiseOperations() {
val x = 0b0100 // 4
val y = 0b0110 // 6
val bits = 2
val shl2bits = x shl bits //左移2位是16(10000)
val shl2bits1 = x.shl(bits) //函数式写法
println("$x(${x.toString(2)}) 左移 $bits 位是 $shl2bits(${shl2bits.toString(2)})")
val shr2bits = x shr bits //右移2位是1
val shr2bits1 = x.shr(bits) //函数式写法
println("$x(${x.toString(2)}) 右移 $bits 位是 $shr2bits(${shr2bits.toString(2)})")
val ushr2bits = x ushr bits // 无符号右移2位是1
val ushr2bits1 = x.ushr(bits) // 函数式写法
println("$x(${x.toString(2)}) 无符号右移 $bits 位是 $ushr2bits(${ushr2bits.toString(2)})")
val xAndy = x and y // x与y是4(100)
val xAndy1 = x.and(y) // 函数式写法
println("$x(${x.toString(2)}) 与 $y(${y.toString(2)}) 是 $xAndy(${xAndy.toString(2)})")
val xOry = x or y // x或y是6(110)
val xOry1 = x.or(y) //函数式写法
println("$x(${x.toString(2)}) 或 $y(${y.toString(2)}) 是 $xOry(${xOry.toString(2)})")
val xXory = x xor y //x异或y是2(0b10)
val xXory1 = x.xor(y) //函数式写法
println("$x(${x.toString(2)}) 异或 $y(${y.toString(2)}) 是 $xXory(${xXory.toString(2)})")
val inv = x.inv() // -5(-101) 只有函数式写法
println("$x(${x.toString(2)}) 按位取反是 $inv(${inv.toString(2)})")
}
# 浮点数比较
- 相等检查:
a == b
anda != b
- 大小比较:
a < b
,a > b
,a >= b
,a <= b
- 范围实例化和范围检查:
a..b
,x in a..b
,x !in a..b
- 表达式比较和平常数学一样
- 预封装函数的浮点数比较则是字面相等则等,负0.0小于0.0
- 预封装函数的NaN等于自身
- 预封装函数的NaN大于一切,包括大于无穷大(POSITIVE_INFINITY)
- 预封装函数的-0.0小于0.0
/**
* 浮点数比较
*/
fun floatPointNumbersComparision(){
//表达式比较和平常数学一样
println("1129.812 == 1129.8120 is "+(1129.812 == 1129.8120)) //true
println("-0.0 == 0.0 is "+(-0.0 == 0.0)) //true
println(Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY) //true
println("Double.NaN == Double.NaN is "+(Double.NaN == Double.NaN)) //false NaN不与任何值相等,包括自身
println(Double.NaN == Double.POSITIVE_INFINITY) //false
println(Double.NaN > Double.POSITIVE_INFINITY) //false
println(Double.NaN < Double.POSITIVE_INFINITY) //false
//用预封装的方法表现不太一样,原则是字面相等即相等,负0小于0
println(listOf(Double.NaN) == listOf(Double.NaN)) //true
println(listOf(-0.0) == listOf(0.0)) //false
println(listOf(Double.POSITIVE_INFINITY) == listOf(Double.POSITIVE_INFINITY)) //true
println(listOf(13.0,-13.0,Double.NaN, Double.POSITIVE_INFINITY,-0.0,0.0).sorted()) //[-13.0, -0.0, 0.0, 13.0, Infinity, NaN]
println(arrayOf(13.0,-13.0,Double.NaN, Double.POSITIVE_INFINITY,-0.0,0.0).sorted()) //[-13.0, -0.0, 0.0, 13.0, Infinity, NaN]
}
# 无符号整型
类型 | 位宽 | 值范围 |
---|---|---|
UByte | 8 | 0~2^8 |
UShort | 16 | 0~2^16 |
UInt | 32 | 0~2^32-1 |
ULong | 64 | 0~2^64-1 |
u/U
- 标记无符号数字
fun unsignIntegerTypes(){
//指定类型
val ub: UByte = 1u
val us: UShort = 1u
val ui: UInt = 1U
val ul: ULong = 1U
//明确标记为UL
val ul1 = 1UL
//以下自动推断类型
val x = 13u //uInt
val y = 0xFFFF_FFFF_FFFFu //ULong
}
# 布尔
- 取值:
true
,false
,null
- 支持的操作符:
!
,||
,&&
- 操作符优先级由高到低
!
,&&
,||
/**
* 布尔类型的定义与操作
*/
private fun booleanOperation() {
val blNull: Boolean? = null
val blTrue = true
val blFalse = false
// println(!blNull) // null值不能参与运算
println(!blTrue) //false
println(blTrue && blFalse) //false
println(blTrue || blFalse) //true
//检查优先级
println(!blTrue || blTrue) //true
println(!blTrue && blFalse ) //false
print(blFalse || blFalse && blTrue) //false
}
# 字符
- 用单引号引起来,例:
'a'
,'1'
- 支持转义字符,用
\
标识,支持Unicode转义序列语法:\uFF01
\t
- tab\b
- backspace\n
- newline(LF)\r
- carriage return(CR)\'
- single quotation mark\"
- double quotation mark\\
- backslash(反斜杠)\$
- dollar sign
private fun charDefinition() {
val c = '1'
val c1: Char = 'a'
val c2 = '\u0062'
val c3 = '\uFF01'
println("$c$c1$c2$c3") // 1ab!
//特殊字符
val tab = '\t'
val backspace = '\b'
val n = '\n'
val r = '\r'
val singleQuotation = '\''
val doubleQuotation = '\"'
val backslash = '\\'
val dollarSign = '\$' //直接用$也可以
println("$tab$backspace$n$r$singleQuotation$doubleQuotation$backslash$dollarSign")
}
# 字符串
- 双引号引起来:
"ab\$c 1$23"
- 字符串的字符可以通过索引访问,str[i]
- 字符支持
for in
遍历- 字符串支持
+
号连接,保证第一个元素是字符串即可- 转义字符串,即单行字符串
- 多行字符串(支持变量,不支持转义):
""" """
- 多行字符串输出
$
符号要用${'$'}
格式
/**
* 字符串定义
*/
private fun stringDefinition(){
val str = "ab\$c 1$23" // ab$c 1$23
val str1 = "abc\n123" // abc换行123
val str2 = "$str${str1.uppercase()}" // ab$c 1$23ABC
val multilineStr = """
I am a kotliner,
today learning definition and operation
变量${'$'}str: $str
${"as"}
我想换行\n支持吗?不支持啦
${'$'}后面接数字字符或为空可以直接写:$1112或$
好了,到这吧
""".trimIndent()
println(str)
println("==========")
println(str1)
println("==========")
println(str2)
println("==========")
println(multilineStr) //去掉最小左空格对齐原样输出
}
//result:
/**
ab$c 1$23
==========
abc
123
==========
ab$c 1$23ABC
123
==========
I am a kotliner,
today learning definition and operation
变量$str: ab$c 1$23
as
我想换行\n支持吗?不支持啦
$后面接数字字符或为空可以直接写:$1112或$
好了,到这吧
*/
/**
* 字符串操作
*/
private fun stringOperation(){
println("==========")
//字符串字符的访问
val str = "abc行云流水home"
println(str[5]) //流
for (c in str){
print("$c ")
}
}
//result
/**
==========
流
a b c 行 云 流 水 h o m e
*/
# 数组
尽量使用集合(Collections),性能要求比较高或构建自定义结构时,才需要使用数组
使用构造器创建数组:
Array
使用方法创建数组:
arrayOf()
,arrayOfNulls()
,emptyArray()
数据可以嵌套创建多维数组
# 数组定义
//数组定义
fun arrayDifinition() {
var words1: Array<String> = arrayOf("Paparazzi", "Junior", "Andy", "Celebrity")
var words2: Array<String> = arrayOf("Paparazzi", "Junior", "Andy", "Celebrity")
println(words1 == words2) //false 数组不要直接比较,无意义,永远是false
println(words1.contentEquals(words2)) //true 数组比较用函数
words1 += "Mofar" //添加元素 会生成一个新的数组,尽量用集合类型替代
println(words1.joinToString()) //Paparazzi, Junior, Andy, Celebrity, Mofar
var words3: Array<String> = Array(4) { "" } //构造函数初始化数组
words3[0] = "Paparazzi" //赋值
words3[1] = "Junior"
words3[2] = "Andy"
words3[3] = "Celebrity"
words3 += "Mofar" //添加元素
println(words3.joinToString()) //Paparazzi, Junior, Andy, Celebrity, Mofar
println(words1.contentEquals(words3)) //true
//嵌套数组
val twoDArray = Array(2) { Array<Int>(2) { 0 } }
println(twoDArray.contentDeepToString()) // [[0, 0], [0, 0]]
val threeDArray = Array(3) { Array(3) { Array(4) { 0 } } }
println(threeDArray.contentDeepToString())
// [[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]
//集合
var collectList1 = listOf("Paparazzi", "Junior", "Andy", "Celebrity")
var collectList2 = listOf("Paparazzi", "Junior", "Andy", "Celebrity")
//可以==比较,表示结构内容相同promotion
println(collectList1 == collectList2) //true
}
# 数组操作
访问和修改数组的元素,用
[]
运算符。数组是不变的,数组的元素可变。
TODO: https://kotlinlang.org/docs/arrays.html#access-and-modify-elements
# kotlin语法
# 包声明
- 文件以.kt为后缀。
- 包声明与java一样,在代码文件的开头。
- 源文件可以放在任何文件目录,与包名无关。
- 没有指定包,则默认为
default
包 - 默认导入以下包
- kotlin.*
- kotlin.annotation.*
- kotlin.collections.*
- kotlin.io.*
- kotlin.comparisons.*
- kotlin.ranges.*
- kotlin.sequences.*
- kotlin.text.*
# 函数定义
函数用fun关键字声明,格式: 函数名(参数1:类型, 参数n:类型):返回类型
fun sum(a: Int, b: Int): Int { //格式: 函数名(参数:类型):返回类型 return a + b }
表达式作为函数体,返回类型自动推断
fun sum(a: Int, b: Int) = a + b
public函数必须明确写出返回类型(无返回值除外)
public fun sum(a: Int, b: Int): Int = a + b
无返回值的函数用Unit表示(类似java的void),也可以省略
fun printSum(a: Int, b: Int): Unit { print(a + b) } public fun printSum(a: Int, b: Int){ print(a + b) }
可变长参数函数用vararg关键字标识
fun printVar(vararg arr: Int){ for(v in arr){ print("$v ") } }
lambda(匿名函数),格式:变量名:参数类型 -> 返回类型 = {参数列表 -> 函数表达式}
fun main(args: Array<String>){ val sumLd:(Int,Int) -> Int = {x,y -> x+y} print(sumLd(13,12)) }
← kotlin