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 = 0
        for (ch in key) {
            if (!ch.isLetter()) {
                continue
            }
            if (map[ch - 'a'].toInt() == 0) {
                map[ch - 'a'] = 'a' + index
                index++
            }
        }

        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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构:单链表

文章目录 &#x1f349;前言&#x1f349;基本概念&#x1f349;链表的分类&#x1f34c;单链表节点的结构&#x1f34c;创建节点&#x1f34c;打印链表&#x1f34c;插入和删除&#x1f95d;尾插&#x1f95d;头插&#x1f95d;尾删&#x1f95d;头删&#x1f95d;指定位置之前…

【Python大数据笔记_day05_Hive基础操作】

一.SQL,Hive和MapReduce的关系 用户在hive上编写sql语句,hive把sql语句转化为MapReduce程序去执行 二.Hive架构映射流程 用户接口: 包括CLI、JDBC/ODBC、WebGUI&#xff0c;CLI(command line interface&#xff09;为shell命令行&#xff1b;Hive中的Thrift服务器允许外部客户端…

设计模式JAVA

1 创建型 如何合理的创建对象&#xff1f; 1.1 单例模式 字面意思就是只能创建一个对象实例时使用。 例如&#xff0c;Windows中只能打开一个任务管理器&#xff0c;这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费&#xff0c;或出现各个窗口显示内容的不一致等…

【自动化测试】Pytest框架 —— 跳过测试和失败重试

1、Pytest跳过测试用例 自动化测试执行过程中&#xff0c;我们常常出现这种情况&#xff1a;因为功能阻塞&#xff0c;未实现或者环境有问题等等原因&#xff0c;一些用例执行不了&#xff0c; 如果我们注释掉或删除掉这些测试用例&#xff0c;后面可能还要进行恢复操作&#…

Cannot run program “D:\c\IntelliJ IDEA 2021.1.3\jbr\bin\java.exe“

如果你的idea在打开后出现了这个故障 Cannot run program "D:\c\IntelliJ IDEA 2021.1.3\jbr\bin\java.exe" (in directory "D:\c\IntelliJ IDEA 2021.1.3\bin"): CreateProcess error2, 系统找不到指定的文件。 打开IDEA的设置 file --> settings --&…

springboot中如何同时操作同一功能

问题描述 测试阶段&#xff0c;由于存在某一功能的同时操作&#xff0c;该功能还是入库逻辑&#xff0c;此时若不进行处理&#xff0c;会造成插入表中多条重复数据&#xff0c;为此该问题需要修复。 解决办法 在接口开始进行对是否存在某个key值的判断&#xff0c;若不存在&…

本地数据库迁移到云端服务器

工具迁移xtrabackup 创建云服务器——通过云服务器提供的公网地址远程连接XShell——利用迁移工具将数据库从本地迁移到云服务器 &#xff08;1&#xff09;创建云服务器 &#xff08;2&#xff09;远程连接XShell &#xff08;3&#xff09;yum安装mysql &#xff08;4&…

Oracle(11)Managing Tables

Managing Tables 管理表 目标&#xff1a; 识别存储数据的各种方法概述甲骨文数据类型区分扩展ROWID与限制ROWID勾勒出一行的结构创建常规表和临时表管理表中的存储结构重新组织、截断和删除表删除表中的列 一、基础知识 1、Oracle Built-in Data Types Oracle内置数据类型 2…

使用Redis实现缓存及对应问题解决

一、为什么需要Redis作缓存&#xff1f; 在业务场景中&#xff0c;如果有些数据需要极高频的存取&#xff0c;每次都要在mysql中查询的话代价太大&#xff0c;假如有一个存在于客户端和mysql之间的存储空间&#xff0c;每次可以在这空间中进行存取操作&#xff0c;就会减轻mys…

视频特效编辑软件 After Effects 2022 mac中文版介绍 (ae 2022)

After Effects 2022 mac是一款视频特效编辑软件&#xff0c;被称为AE&#xff0c;拥有强大的特效工具&#xff0c;旋转&#xff0c;用于2D和3D合成、动画制作和视觉特效等&#xff0c;效果创建电影级影片字幕、片头和过渡&#xff0c;是一款可以帮助您高效且精确地创建无数种引…

某平台简单尝试一次密码逆向

1、查看表单数据 发现密码加密 2、控制台搜索password 发现他在欺负我看不懂拼音 3、第一次断点调试失败 断点后随便填写账号密码登录&#xff0c;发现失败 4、控制台搜索 jiami 又找到了一个函数 5、断点成功 重新登录后断点成功 jiami function(password) {var e passw…

Go-服务注册和发现,负载均衡,配置中心

文章目录 什么是服务注册和发现技术选型 Consul 的安装和配置1. 安装2. 访问3. 访问dns Consul 的api接口go操作consulgrpc下的健康检查grpc的健康检查规范动态获取可用端口号 负载均衡策略1. 什么是负载均衡2. 负载均衡策略1. 集中式load balance2. 进程内load balance3. 独立…

爬虫项目-爬取股吧(东方财富)评论

1.最近帮别人爬取了东方财富股吧的帖子和评论&#xff0c;网址如下&#xff1a;http://mguba.eastmoney.com/mguba/list/zssh000300 2.爬取字段如下所示&#xff1a; 3.爬虫的大致思路如下&#xff1a;客户要求爬取评论数大于5的帖子&#xff0c;首先获取帖子链接&#xff0c…

剑指JUC原理-16.读写锁

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

JavaEE进阶3

传递数组: 当我们请求中,同一个参数有多个时,浏览器就会帮我们封装成一个数组 用逗号进行分割也是可以的(有的浏览器不能直接使用逗号,需要我们去转码) 传递集合: HTTP 状态码(不是后端自定义的) 2XX:成功 3XX:重定向 4XX:客户端错误 5XX:服务器错误 业务状态码:HTTP响应…

【NLP】特征提取: 广泛指南和 3 个操作教程 [Python、CNN、BERT]

什么是机器学习中的特征提取&#xff1f; 特征提取是数据分析和机器学习中的基本概念&#xff0c;是将原始数据转换为更适合分析或建模的格式过程中的关键步骤。特征&#xff0c;也称为变量或属性&#xff0c;是我们用来进行预测、对对象进行分类或从数据中获取见解的数据点的…

2.3.3 交换机的RSTP技术

实验2.3.3 交换机的RSTP技术 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施1.交换机的基本配置。2.开启交换机的STP。3.配置SW3A和SW3B上STP的优先级。将SW3A配置为根交换机&#xff0c;SW3B配置为备用根交换机。4.配置SW2A和SW2B的边缘接口 六、任务验收七、…

Azure 机器学习 - 使用Python SDK训练模型

目录 一、环境准备二、工作区限制三、什么是计算目标&#xff1f;四、本地计算机五、远程虚拟机六、Apache Spark 池七、Azure HDInsight八、Azure Batch九、Azure Databricks十、Azure Data Lake Analytics十一、Azure 容器实例十二、Kubernetes 了解如何用 SDK v1 将 Azure 计…

11-Docker-Redis集群部署

00-前言 在工作环境中&#xff0c;我们常常被要求配置多种集群&#xff0c;Redis 集群是最常见的入门需要掌握的集群配置方法&#xff0c;在之前的学习中&#xff0c;我们学习掌握了分布式存储的算法&#xff0c;本质上集群的部署就是通过分布式存储算法将数据分发部署好的不同…

windows上 Nexus 批量上传 maven依赖npm依赖

windows上 Nexus 批量上传 maven依赖/npm依赖 前言&#xff1a;windows系统上要有git环境&#xff0c;不然sh文件执行不了 1.批量上传maven依赖 设置脚本&#xff0c;把脚本放在依赖包的根目录执行&#xff0c;脚本名为upload.sh #!/bin/bash# 定义变量 while getopts &quo…