Kotlin基础数据类型和运算符

原文链接 Kotlin Types and Operators

Kotlin是新一代的基于JVM的静态多范式编程语言,功能强大,语法简洁,前面已经做过Kotlin的基本的介绍,今天就来深入的学习一下它的数据类型和运算操作符。

数据类型

与大部分语言不同的是,在Kotlin中一切皆为对象(Everything is an object),它没有像Java/C++那样,是没有基础数据类型(primitive types)的,都是对象,因此也不会有像Java那样的box和auto box的麻烦。box和autobox对于单独使用基础数据类型时没啥问题,比如一个方法add(Integer),会进行自动装箱和拆箱。但如果在集合中使用就不一样了,比如array of int与array of Integer是完全不同的数据类型,以及list of int与list of Integer也是完全不同的数据类型,在这些场景里就会相当麻烦,要进行转换,详细可以参考这篇文章。

变量类型的声明

类型是放在变量之后,这样可以先强调变量的名字,后关注其类型,如:

var count: Int
var message: String
fun double(x: Int): Int {return x + x
}

类型推断

虽然Kotlin是静态强类型语言,也就是说在编译的时候,编译器必须知道你的数据是什么类型的,这与Java和C++等是一样的,但并不意味着你必须为每个变量声明它的类型。变量的声明,是告诉编译器有一个什么类型的变量,以及叫什么,就比如在函数中的参数列表,就是变量的声明;而变量的定义,则是在声明的同时,要给变量赋值。

那么,当定义变量的时候,编译器是能够直接推断出来它的类型的,这个时候就可以省去类型的声明,Kotlin语言力求简洁,凡是能推断出变量的类型时都可以省去类型的声明,如定义变量的时候,如在lambda中,或者在函数的返回值中。

val PI = 3.14 // Double
val PI: Double = 3.14 // 与上面的效果一样

数字类型(Numbers)

数字类型与大部分语言一样,特别的,它与Java语言是一样的,都是有符号的,即数字最高数位代表符号。

整数

与Java语言一样,有四大整数具体类型,8位的Byte,16位的Short,32位的Int以及64位的Long。它们的范围如下:

TypeSize(bits)Min valueMax value
Byte8-128127
Short16-32768 (-2^15)32767 (2^15 - 1)
Int32-2,147,483,648 (-2^31)2,147,483,647 (2^31 - 1)
Long64-9,223,372,036,854,775,808 (-2^63)9,223,372,036,854,775,807 (2^63 - 1)

当然了,每个类型都有其最大值和最小值的常量可以直接引用,不用自己手动写。另外需要注意的是非10进制的字面常量都是二的补码形式,并不是直观的二进制,详细的可以参考另外一篇文章。

浮点数

有Float和Double,它们的定义如下:

TypeSize (bits)Significant bitsExponent bitsDecimal digits
Float322486-7
Double64531115-16

#### 字面常量(Literals) 字面常量是指直接写在代码中的数字,默认的是Int和Double,如果需要指定类型,可以用标记或者给变量指定类型,如:
val one = 1 // Int
val threeBillion = 3000000000 // Long, exceeding Int, so it is Long
val aLong = 1L // mark it as Long
val oneByte: Byte = 1 // Byte
val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float, actual value is 2.7182817

常见的语法糖:

  • 浮点数可以用乘方形式如123.5e10
  • 可以下划线(underscore)来加强可读性,如1_000_000
  • 16进制用0x打头,如0xFF_AB
  • 二进制用0b打头,如0b1101_1111

布尔类型(Booleans)

字符类型(Characters)

用两个单引号来表示,如val ch = ’ ’

需要注意因为字符是对象,所以不能直接与整数进行比较,需要转化为整数,这点不像Java,在Java中字符是可以直接与整数比较的。

        val map = CharArray(26)var index = 0for (ch in key) {if (!ch.isLetter()) {continue}if (map[ch - 'a'].toInt() == 0) {map[ch - 'a'] = 'a' + indexindex++}}return message.map { if (it.isLetter()) map[it - 'a'] else it }.joinToString("")

字符串类型(Strings)

可以视为字符的数组,是一个不可变对象(immutable object),用两个双引号来表示,如

val message = "Hello, world"

字符串拼接用加号+

val name = "John"
val message = "Hello" + name

当然了,直接用加号拼接效率不好,一般情况下可以直接用字符串模板更好一些。

字符串模板

这是一个强大且方便的内置功能,相当于简化版本的String.format,可以在字符串用**美元符$**来引用一个变量的值,如果是有方法调用或者运算或者成员引用等情况可以加花括号:

val name = "John"
val message = "Hello, $name"
println("Length is ${name.length}")
字符遍历

与Java不同的是,字符串在Kotlin里面更像是字符数组,或者说一个列表,因此可以直接遍历:

val mesage = "The quick fox jumps over the lazy dog"
for (ch in message) {println(ch)
}

in是一个强大的操作符,可以用于集合的遍历。另外,字符串可以像列表一样进行函数式的操作,如判断是否包含某个字符:

if (message.any {it == ch}) {println("$ch is in $message")
}

数组类型(Arrays)

数组Array是一个具体类型为T的数组,这是通用的数组,另外还有一种就是基本数组类型数组,我们分别来看一下

通用对象数组 Array<T>

这是适用于所有对象的数组,有两种构造方式,一是通过arrayOf(),直接传入数组的具体值,另外就是用构造方法Array(size)

val heights = arrayOf(240, 360, 480, 640)
val classes = arrayOf("John", "Harden", "Kevin", "Stephen")
val guards: Array<String> = Array(5)
guards[0] = "Stephen"
guards[1] = "Kevin"

还有一种用lambda方式来构造数组,可以非常方便的实现数组的定义:

val asc = Array(5) { i -> (i * i).toString() }
// asc = ["0", "1", "4", "9", "16"]

需要注意的是这里的类型T都是对象。但其实,对于基础类型的数组,如果都box成为对象效率并不高,虽然Kotlin中并没有真的基础数据类型,但涉及到数组这种批量的数据时,使用基础类型能提升很大的效率,因此还有专门用于基础类型的数组类型。

基础类型数组 IntArray和FloatArray

其实有很多,基础的类型都有IntArray, ByteArray, ShortArray, FloatArray, DoubleArray。而且需要注意的是Array<Int>与IntArray是两个数组类型,它们并不一样,这个区别与Java中的Integer[]和int[]是类似的。而且IntArray与Array<T>也没什么关系,也不是什么继承关系。但是它们表现出来的使用方法是一样的。

val heights = intArrayOf(240, 360, 480, 640)
val squares = IntArray(5) { i -> i * i } // [0, 1, 4, 9, 16]
val arr = IntArray(5) { 42 } // [42, 42, 42, 42, 42]
val bundle = arrayOf(intArrayOf(1080, 720), intArrayOf(1920, 1080)) // bundle type is Array<IntArray>

运算操作符

运算操作符与大部分语言是一样的。

算术运算符

也即是常规的算术操作符,+(加) -(减)*(乘) /(除) %(取模),这些都是二元操作符,也就是需要两个操作数才能使用。

还有单元操作符,如自增++自减–,当然也分前置和后置,区别与Java/C++中一样。

操作符与**赋值符=**可以配合一起使用,如a += b等同于a = a + b,a /= c等同于 a = a / c

逻辑运算符

双元操作符: && 逻辑与,|| 逻辑或,它们的操作数必须 是布尔型,且返回值也是布尔。

与其他语言一样,这两个操作符是short-circiut的或者说是lazy的,也即a && b,如果a是false,那就不去管b了,因为不影响结果;a || b也一样,如果a是true就不去管b了。

还有单元操作符**! 逻辑非**。一个有意思的地方在于,逻辑非可以与一些操作符合起来使用,而不是直接写在表达式之外,比如,下面两种写法等效:

if (!(a in asc)) {...}
if (a !in asc) {...}
if (b !is Array) {...}
if (!(b is Array)) {...}

位运算符

位运算符比较特殊,与大部分语言不一样。

移位
操作符含义示例说明
shr向右移位a shr 1把a向右移1位
shl向左移位a shl 1a向左移1位
ushr无符号向右移位a ushr 1(包含符号位)向右移1位
按位逻辑运算
操作符含义示例说明
and按位与a and 1a与1按位与
or按位或a or 1a与1按位或
xor按位异或a xor 1a与1按位异或
inv按位取反inv(a)把a按位取反

这些操作符看起来可能比较怪,然后更怪异的是位运算操作符不能与**赋值符=**一起使用,只能这样写:

a = a or b
c = c xor (1 shl 3)

事实上位运算不是操作符,它们是一种函数,叫做infix函数,简写了把括号省略了,看起来就像操作符一样,但它们并不是操作符。

运算符重载

与C++中的运算符重载类似,Kotlin中支持运算符重载,本质上它们都是对象定义的方法,但支持重载为运算符。

比如说加法,a + b,可以写成方法调用的形式a.plus(b);b or c等同于b.or©,!a等同于a.not()。

运算符的优先级

尽管是有默认的优先级的,但强烈建议使用括号以减少歧义和增强可读性,更可以避免一些难以察觉的Bug。

参考资料

  • Basic types
  • Using Bitwise Operators in Kotlin
  • Kotlin Bitwise and Bitshift Operations
  • Kotlin Operators
  • Kotlin - Operators
  • Kotlin Operators

原创不易,打赏点赞在看收藏分享 总要有一个吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/136961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

socket编程中的EINTR是什么?

socket编程中的EINTR是什么? 在socket编程中&#xff0c;我们时常在accept/read/write等接口调用的异常处理的部分看到对于EINTR的处理&#xff0c;例如下面这样的语句&#xff1a; repeat: if(read(fd, buff, size) < 0) {if(errno EINTR)goto repeat;elseprintf("…

三菱FX3U系列-定位指令

目录 一、简介 二、指令形式 1、相对定位[DRVI、DDRVI] 2、绝对定位[DRVA、DDRVA] 三、总结 一、简介 定位指令用于控制伺服电机或步进电机的位置移动。可以通过改变脉冲频率和脉冲数量来控制电机的移动速度和移动距离&#xff0c;同时还可以指定移动的方向。 二、指令形…

Linux下的环境变量【详解】

Linux下的环境变量 一&#xff0c;环境变量的概念1 概述2 环境变量的分类3 常见的环境变量4 查看环境变量4.1 shell变量4.2 查看环境变量 5 添加和删除环境变量5.1 添加环境变量5.2 删除环境变量 6. 通过代码如何获取环境变量6.1 命令行的第三个参数6.2 通过第三方变量environ获…

Linux 的热插拔机制通过 Udev(用户空间设备)实现、守护进程

一、Udev作用概述 udev机制简介udev工作流程图 二、Linux的热拔插UDEV机制 三、守护进程 守护进程概念守护进程在后台运行基本特点 四、守护进程和后台进程的区别 一、Udev作用概述 udev机制简介 Udev&#xff08;用户空间设备&#xff09;是一个 Linux 系统中用于动态管…

微信号绑定50个开发者小程序以后超额如何删除不用的

我们在开发微信小程序的时候&#xff0c;当前开发者工具登录的必须是该小程序的开发者才能进行小程序的开发&#xff0c;添加开发者的步骤是&#xff1a; 添加开发者 1、进入微信开放平台&#xff0c;然后扫码进入管理平台 2、找到下图所示位置 3:、输入要添加的微信账号&am…

LCD英文字模库(16x8)模拟测试程序

字模 字模&#xff0c;就是把文字符号转换为LCD能识别的像素点阵信息。 电子发烧友可能都熟悉字模的用途。就是调用者通过向LCD模块发送字模数据&#xff0c;LCD根据字模数据在LCD面板上相应的像素描绘出图形或文字。 现在&#xff0c;大部分的LCD都内置了字模库&#xff0c…

11-09 周四 CNN 卷积神经网络基础知识

11-09 周四 CNN 卷积神经网络 时间版本修改人描述2023年11月9日09:38:12V0.1宋全恒新建文档 简介 学习一下CNN&#xff0c;卷积神经网络。使用的视频课程。视觉相关的任务&#xff1a; 人脸识别 卷积网络与传统网络的区别&#xff1a; <img altimage-20231109094400591 s…

电脑怎么录制视频,录制的视频怎么剪辑?

在现今数字化的时代&#xff0c;视频成为了人们日常生活中不可或缺的一部分。因此&#xff0c;对于一些需要制作视频教程、录制游戏或者是进行视频演示的人来说&#xff0c;电脑录屏已经成为了一个必不可少的工具。那么&#xff0c;对于这些人来说&#xff0c;如何选择一个好用…

Zigbee—网络层地址分配机制

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;孤雏 0:21━━━━━━️&#x1f49f;──────── 4:14 &#x1f504; ◀️ ⏸ ▶️ ☰ &#x1f497;关注…

大厂面试题-MySQL中的RR隔离级别,到底有没有解决幻读问题?

就MySQL中的RR(Repeatable Reads)事务隔离级别&#xff0c;到底有没有解决幻读问题发起了激烈的讨论。 一部分人说有&#xff0c;一部分人说没有。 结论&#xff0c;MySQL中的RR事务隔离级别&#xff0c;在特定的情况下会出现幻读的问题。 所谓的幻读&#xff0c;表示在同一…

景联文科技加入中国人工智能产业发展联盟(AIIA),与行业各方共促AI产业发展

近日&#xff0c;景联文科技加入中国人工智能产业发展联盟&#xff08;AIIA&#xff09;&#xff0c;与行业各方共同挖掘人工智能数据的更多价值&#xff0c;破解中国人工智能AI数据短缺难题。 中国人工智能产业发展联盟&#xff08;简称AIIA&#xff09;是在国家发改委、科技部…

GIS入门,xyz地图瓦片是什么,xyz数据格式详解,如何发布离线XYZ瓦片到nginx或者tomcat中

XYZ介绍 XYZ瓦片是一种在线地图数据格式,由goole公司开发。 与其他瓦片地图类似,XYZ瓦片将地图数据分解为一系列小的图像块,以提高地图显示效率和性能。 XYZ瓦片提供了一种开放的地图平台,使开发者可以轻松地将地图集成到自己的应用程序中。同时,它还提供了高分辨率图像和…

红海云签约和兆服饰,科技引领服饰行业人力资源数字化转型

和兆服饰从事多品牌多品类经营管理&#xff0c;旗下拥有POLOSPORT、POLOKIDS、CARTELO等国际品牌。作为一个主打POLO文化的服饰品牌&#xff0c;诞生于美国的POLOSPORT拥有现代感的产品设计、系列化的产品搭配、全方位的服务&#xff0c;是最具美国马球精神的休闲时尚服饰品牌之…

攻防世界题目练习——Web引导模式(四)(持续更新)

题目目录 1. shrine2. very_easy_sql3. fakebook 1. shrine 打开网页题目内容如下&#xff1a; 是一段代码&#xff0c;我们把它还原一下&#xff1a; import flask import osapp flask.Flask(__name__) app.config[FLAG] os.environ.pop(FLAG) #这里应该是将config配置里…

【Docker】设置容器系统字符集zh_CN.UTF-8退出失效:关于Docker容器配置环境变量,再次进入失效问题

设置容器系统字符集zh_CN.UTF-8退出失效&#xff1a;关于Docker容器配置环境变量&#xff0c;再次进入失效问题 修改正在运行的Docker容器内的字符集: 先进入Docker容器&#xff1a;docker exec -it 容器ID /bin/bash查看是否支持中文字符集&#xff1a;locale -a | grep zh&a…

PCIe寄存器之二

关键字索引&#xff1a; CAP_PM 对应&#xff1a;Capabilities: [c0] Power Management CAP_MSI 对应&#xff1a;Capabilities: [c8] MSI CAP_MSIX对应&#xff1a;Capabilities: [e0] MSI-X CAP_EXP 对应&#xff1a;Capabilities: [70] Express (v2) Endpoint 以上 [] 内的…

uni-app前端H5页面底部内容被tabbar遮挡

问题&#xff1a; 在用uniapp写小程序的时候&#xff0c;底部有一部分内容没显示出来&#xff0c;被底部的tabbar遮挡住了 解决&#xff1a; 给最外部的view设置样式padding-bottom: var(--window-bottom)&#xff0c;如下 参考&#xff1a; 参考1 参考2 使用 uni-app 框…

推送效率低?MobPush带着APP消息推送一站式解决方案来了

随着移动应用竞争的日趋激烈&#xff0c;如何拉新促活&#xff0c;保持用户粘性成为各大APP的运营的焦点和核心。作为一种有效的营销和用户保留工具。APP消息推送可以有效提高用户参与度&#xff0c;增强用户忠诚度&#xff0c;并最终提高业务效益。然而随着各大APP推送的高度同…

UML与PlantUML简介

UML与PlantUML 1、UML与PlantUML概述2、PlantUML使用 1、UML与PlantUML概述 UML&#xff08;Unified Modeling Language&#xff09;是一种统一建模语言&#xff0c;为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言&#xff0c;独立于任何具体程序设计语言…

YOLOv8-Seg改进: 分割小目标系列篇 | SPD-Conv,提升分割小目标和弱小分割图精度

🚀🚀🚀本文改进:SPD-Conv由一个空间到深度(SPD)层和一个无卷积步长(Conv)层组成,可以应用于大多数CNN体系结构,特别是在处理低分辨率图像和分割小目标等更困难的任务时。 🚀🚀🚀SPD-Conv 分割小目标检测首选,暴力涨点 🚀🚀🚀YOLOv8-seg创新专栏:http:…