Kotlin学习笔记(2)——数据类型详解

kotlin2.png

引言:Kotlin的数据类型和Java是大致相同的,但是他们的写法不同,并且类型之间的转换也存在着差异。

一、数值类型

1、Kotlin中的数字的内置类型(接近与Java),其关键字为:

  • Byte=> 字节 => 8位
  • Short => 短整型 => 16位
  • Int => 整型 => 32位
  • Long => 长整型 => 64位
  • Float => 浮点型 => 32位
  • Double => 双精度浮点型 => 64位
var a: Byte = 2                                                                                                 a = 2
var b: Short = 2                                                                                               b = 2
var c: Int = 2                                                                                                    c = 2
var d: Long = 2L //长整型由大写字母L标记                                                       d = 2
var e: Float = 2f //单精度浮点型由小写字母f或大写字符F标记                            e = 2.0
var f: Double = 2.0                                                                                           f = 2.0

2、进制数

  • 二进制数
  • 八进制数(Kotlin不支持)
  • 十进制数
  • 十六进制数
var g = 0x0F //十六进制数                                        g = 15
var h = 0b00001011 //二进制数                               h = 11
var k = 123 //十进制数                                             k = 123

3、数字类型字面常量的下划线

作用:分割数字进行分组,使数字常量更易读
例:

val oneMillion = 1_000_000 
val creditCardNumber = 1234_5678_9012_3456L 
val socialSecurityNumber = 999_99_9999L 
val hexBytes = 0xFF_EC_DE_5E 
val bytes = 0b11010010_01101001_10010100_10010010 

println("oneMillion => $oneMillion") 
println("creditCardNumber => $creditCardNumber") 
println("socialSecurityNumber => $socialSecurityNumber") 
println("hexBytes => $hexBytes") 
println("bytes => $bytes")

输出结果为:

oneMillion => 1000000 
creditCardNumber => 1234567890123456 
socialSecurityNumber => 999999999 
hexBytes => 4293713502 
bytes => 3530134674

4、装箱与拆箱

* 装箱与拆箱

在Kotlin中,存在数字的装箱,但是不存在拆箱。因为Kotlin是没有基本数据类型的,Kotlin是万般皆对象的原则。故不存在和Java中的类似int是数据类型,Integer是整型的引用类型。
在Kotlin中要实现装箱操作。首先要了解可空引用。即类似Int?(只限数值类型)这样的。
例:

val numValue: Int = 123 
//装箱的过程,其实装箱之后其值是没有变化的 
val numValueBox: Int? = numValue 
println("装箱后: numValueBox => $numValueBox")

输出结果为:

装箱后: numValueBox => 123

* 两个数值的比较

判断两个数值是否相等(==),判断两个数值在内存中的地址是否相等(===),其实上面的装箱操作之后其内存中的地址根据其数据类型的数值范围而定。
例:

val numValue: Int = 128 
val numValueBox: Int? = numValue 

/* 比较两个数字 */ 
var result: Boolean 
result = numValue == numValueBox 
println("numValue == numValueBox => $result") // => true,其值是相等的 

result = numValue === numValueBox 
/* 上面定义的变量是Int类型,大于127其内存地址不同,反之则相同。 
这是`kotlin`的缓存策略导致的,而缓存的范围是` -128 ~ 127 `。 
故,下面的打印为false */ 
println("numValue === numValueBox => $result")

输出结果为:

numValue == numValueBox => true 
numValue === numValueBox => false

5、转换

  • 显式转换
    较小的类型不会被隐式转换为更大的类型,故而系统提供了显式转换。提供的显式转换方法如下:
  1. toByte() => 转换为字节型
  2. toShort() => 转换为短整型
  3. toInt() => 转换为整型
  4. toLong() => 转换为长整型
  5. toFloat() => 转换为浮点型
  6. toDouble() => 转换为双精度浮点型
  7. toChar() => 转换为字符型
  8. toString() => 转换为字符串型

例:

var numA: Int = 97 
println(numA.toByte()) 
println(numA.toShort()) 
println(numA.toInt()) 
println(numA.toLong()) 
println(numA.toFloat()) 
println(numA.toDouble()) 
println(numA.toChar()) 
println(numA.toString())

输出结果为:

97 
97 
97 
97
97.0 
97.0
a 
97
  • 隐式转换
    类型是从上下文推断出来的,即算术运算则被重载为适当的转换
// 30L + 12 -> Long + Int => Long 
val num = 30L + 12 
print(num)                //42

6、位运算符

Kotlin中对于按位操作,和Java是有很大的差别的。Kotlin中没有特殊的字符,但是只能命名为可以以中缀形式调用的函数,下列是按位操作的完整列表(仅适用于整形(Int)和长整形(Long)):

  1. shl(bits) => 有符号向左移 (类似Java的<<)
  2. shr(bits) => 有符号向右移 (类似Java的>>)
  3. ushr(bits) => 无符号向右移 (类似Java的>>>)
  4. and(bits) => 位运算符 and (同Java中的按位与)
  5. or(bits) => 位运算符 or (同Java中的按位或)
  6. xor(bits) => 位运算符 xor (同Java中的按位异或)
  7. inv() => 位运算符 按位取反 (同Java中的按位取反)

例:

/* 位运算符 支持序列如下:shl、shr、ushr、and、or、xor */ 
var operaNum: Int = 4 

var shlOperaNum = operaNum shl(2) 
var shrOperaNum = operaNum shr(2) 
var ushrOperaNum = operaNum ushr(2) 
var andOperaNum = operaNum and(2) 
var orOperaNum = operaNum or(2) 
var xorOperaNum = operaNum xor(2) 
var invOperaNum = operaNum.inv() 

println("shlOperaNum => $shlOperaNum \n " + 
            "shrOperaNum => $shrOperaNum \n " + 
            "ushrOperaNum => $ushrOperaNum \n " + 
            "andOperaNum => $andOperaNum \n " + 
            "orOperaNum => $orOperaNum \n " + 
            "xorOperaNum => $xorOperaNum \n " + 
            "invOperaNum => $invOperaNum")

输出结果为:

shlOperaNum => 16 
shrOperaNum => 1 
ushrOperaNum => 1 
andOperaNum => 0 
orOperaNum => 6 
xorOperaNum => 6 
invOperaNum => -5

二、布尔类型(Boolean)

1、关键字

Boolean关键字表示布尔类型,并且其值有true和false

2、逻辑操作符(与Java相同)

  • ' || ' => 逻辑或(或者)
  • ' && ' => 逻辑与(并且)
  • ' ! ' => 逻辑非(取反)

三、字符型(Char)

1、关键字

Char为表示字符型,字符变量用单引号(‘ ’)表示。并且不能直接视为数字,不过可以显式转换为数字。

2、显示转换为其他类型

字符型的变量不仅可以转换为数字,同时也可转换为其他类型
PS:除了可以转换类型外,当变量为英文字母时还支持大小写转换。

3、字符转义

同Java一样,使用某些特殊的字符时,要使用转义。下列是支持的转义序列:

  • \t => 表示制表符
  • \n => 表示换行符
  • \b => 表示退格键(键盘上的Back建)
  • \r => 表示键盘上的Enter键
  • \ => 表示反斜杠
  • ' => 表示单引号
  • " => 表示双引号
  • $ => 表示美元符号,如果不转义在kotlin中就表示变量的引用了
  • 其他的任何字符请使用Unicode转义序列语法。例:'\uFF00'

四、字符串类型(String)

1、关键字

String表示字符串类型。所以字符串的元素可以通过索引操作的字符:str[index]来访问。可以使用for循环迭代字符串:
其中str[index]中的str为要目标字符串,index为索引
例:

val str: String = "kotlin" 
println("str => $str") 

//迭代 
for (s in str){ 
    print(s) 
    print("\t") 
}

输出结果为:

str => kotlin 
k    o    t    l    i    n

2、 字符串字面量

在Kotlin中, 字符串字面量有两种类型:

  • 包含转义字符的字符串 转义包括(\t、\n等),不包含转义字符串的也同属此类型
  • 包含任意字符的字符串 由三重引号(""" .... """)表示
    例:
// 类型1: 
var str1: String = "hello\t\tkotlin" 
println(str1) 
str1 = "hello kotlin" 
println(str1) 

// 类型2: 
val str2 = """ fun main(args: Array<String>){ 
        println("我是三重引号引用的字符串,我可以包含任意字符") 
        } """ 
println(str2)

输出结果为:

hello        kotlin 
hello kotlin 
fun main(args: Array<String>){ 
        println("我是三重引号引用的字符串,我可以包含任意字符") 
        }

PS: 可以使用trimMargin()函数删除前导空格 ,默认使用符号(|)作为距前缀,当然也可以使用其他字符。例:右尖括号(>)、左尖括号(<)等。

3、字符串模板

使用字符串模板的符号为()。在符号后面加上变量名或大括号中的表达式
例:

val text1: String = "我来了!" 
var text2: String = "$text1 kotlin" 
var text3: String = "$text2 ${text1.length} 哈哈!!!!" 
println(text1) 
println(text2) 
println(text3)

输出结果为:

我来了! 
我来了! kotlin 
我来了! kotlin 4 哈哈!!!!

五、数组型(Array)

  • Kotlin中数组由Array<T>表示,可以去看看源码实现,里面就几个方法
  • 创建数组的3个函数
    • arrayOf()
    • arrayOfNulls()
    • 工厂函数(Array())

1、arrayOf()

创建一个数组,参数是一个可变参数的泛型对象
例:

var arr1 = arrayOf(1,2,3,4,5) //等价于[1,2,3,4,5] 
for (v in arr1){ 
        print(v) 
        print("\t") 
} 

var arr2 = arrayOf("0","2","3",'a',32.3f) 
for (v in arr2){ 
        print(v) 
        print("\t") 
}

输出结果为:

1    2    3    4    5 
0    2    3    a    32.3

2、arrayOfNulls()

用于创建一个指定数据类型且可以为空元素的给定元素个数的数组
例:

var arr3 = arrayOfNulls<Int>(3) 

//如若不予数组赋值则arr3[0]、arr3[1]、arr3[2]皆为null 
for(v in arr3){ 
        print(v) 
        print("\t") 
} 

println() 

//为数组arr3赋值 
arr3[0] = 10 
arr3[1] = 20 
arr3[2] = 30 
for(v in arr3){ 
        print(v) 
        print("\t") 
}

输出结果为:

null    null    null 
10    20    30

3、工厂函数

  • 使用一个工厂函数Array(),它使用数组大小和返回给定其索引的每个数组元素的初始值的函数。
  • Array() => 第一个参数表示数组元素的个数,第二个参数则为使用其元素下标组成的表达式
    例:
var arr4 = Array(5,{(index * 2).toString() }) 
for (v in arr4){ 
        print(v) 
        print("\t") 
}

输出结果为:

0    2    4    6    8

4、原始类型数组

  • Kotlin还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:
    • ByteArray => 表示字节型数组
    • ShortArray => 表示短整型数组
    • IntArray => 表示整型数组
    • LongArray => 表示长整型数组
    • BooleanArray => 表示布尔型数组
    • CharArray => 表示字符型数组
    • FloatArray => 表示浮点型数组
    • DoubleArray => 表示双精度浮点型数组
  • PS: Kotlin中不支持字符串类型这种原始类型数组,可以看源码Arrays.kt这个类中并没有字符串数组的声明。而源码中StringArray.kt这个类并不是声明字符串型数组的。
    例:
var intArr: IntArray = intArrayOf(1,2,3,4,5) 
for (number in intArr){ 
        print(number) 
        print("\t") 
} 

println() 

var charArr: CharArray = charArrayOf('a','1','b','c','3','d') 
for (char in charArr){ 
    print(char) 
    print("\t") 
} 

println() 

var longArr: LongArray = longArrayOf(12L,1254L,123L,111L) 
for (long in longArr){ 
    print(long) 
    print("\t") 
}

输出结果为:

1    2    3    4    5 
a    1    b    c    3    d 
12    1254    123    111
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容