日志

2、基本数据类型:数字篇 上

 来源    2020-01-17    0  

基本数据类型

这节课我们先来看看 Kotlin 中都有哪些基本数据类型。

一切皆对象

和 Java 不同,在 Kotlin 的世界中,一切皆为对象。基本数据类型会被自动装箱成对象(但不支持拆箱),都可以访问成员函数和属性。

基本类型

在 Kotlin 中,总共有5种基本数据类型,他们分别是数字、字符、布尔、数组和字符串。

数字

和常见的高级编程语言类似,在 Kotlin 中,对于数字的表示,有整数和浮点(小数)之分。

整数

Kotlin 提供了4种方式来表示整数,它们所占的大小各有不同,取值范围也会随之变化,下表列出了4种整数类型的详细情况:

类型 大小(bits) 最小值 最大值
Byte 8 -128 127
Short 12 -32768 32767
Int 32 -2147483648 2147483647
Long 64 -9223372036854775808 9223372036854775807

默认情况下,在赋值时,只要数值未超过 Int 的取值范围,Kotlin 都会将其推断为 Int 类型。否则,会推断为 Long 类型。当然,我们也可以在赋值时加上“L”后缀,以显式指定变量为 Long 型。
此外,Kotlin 还支持 16 进制和 2 进制的数值表示法。当要表示 16 进制时,其值以“0x开头”;当要表示 2 进制时,其值以“0b”开头;8 进制在 Kotlin 中是不被支持的。
为了阅读方便,自 Kotlin 1.1 起,我们可以给数字添加下划线,以增强数值的可读性。
以下是一些例子:

// byte 类型
val byteSample = 1
// int 类型
val intSample = 1
// long 类型
val longSample = 1L
// 将自动转为 long 类型
val autoToLong = 1000000000
// 16 进制表示法
val hexSample = 0xFF
// 2 进制表示法
val binSample = 0b00001011
// 使数值更易读的下划线表示
val bankCardNum = 4367_4200_6458_0486_097L

浮点数

Kotlin 提供了两种类型用来表示浮点值,即单精度和双精度。和整数类似,这两种类型大小不同,表示的数值范围也有所差异,具体见下表:

类型 大小(bits) 有效数字比特数 指数比特数 十进制位数
Float 32 24 8 6-7
Double 64 53 11 15-16

默认情况下,在赋值时,编译器会默认按照 Double 类型初始化浮点变量。如果我们需要将一个变量显式指定为 Float 类型,需要在值后面加上“F”(大小写皆可) 后缀。特别注意:显式指定时,超过 Float 范围的部分将丢失精度,末位会四舍五入。
参考下面的代码示例:

// double 类型
val doubleSample = 1.2
// double 类型
val doubleSample2 = 1.234e10
// float 类型
val floatSample = 1.2F
// 丢失精度的转换
// 实际值将变为:3.1415927
val fPi = 3.1415926535898F
// 实际值将变为:1.1234568
val fTest = 1.123456789F

隐式转换与显示转换

Kotlin 并不支持类型“隐式拓宽转换”。
何为隐式拓宽转换呢?

fun main(args: Array<String>){
    val intSample = 1;    
    fun doubleOutput(doubleSample: Double){        
        println(doubleSample)    
    }    
    doubleOutput(intSample)
}

上面这段代码中,首先定义了一个值为1的数字变量 intSample,随后实现了一个名为 doubleOutput() 的方法。现在我们还没学过“方法”,不过没关系,我们暂且将其理解成需要一个浮点(Double)类型变量的事物。随后,我们调用了这个方法,将 intSample 的整数类型值交给它。
大家猜猜看,运行这段代码,会有怎样的结果呢?
想好了吗?
答案是:这段代码根本无法正常运行!
结合之前的知识,我们知道,intSample 将会默认成为一个 Int 类型的变量,而 doubleOutput() 方法需要一个浮点 Double 类型。Kotlin 并不支持自动隐式由 Int -> Double 类型的变换。所以语法错误,代码无法运行。这一点和 Java 是完全不同的,如果您之前一直使用 Java 编程语言,要特别注意这一点。
现在,请思考:如果将上述代码改为:

fun main(args: Array<String>){
    val intSample = 1f;    
    fun doubleOutput(doubleSample: Double){        
        println(doubleSample)    
    }    
    doubleOutput(intSample)
}

如此修改,代码可以运行吗?如果可以的话,运行结果会是怎样的呢?
答案是——代码依旧无法运行,因为 Float 无法隐式转为 Double。
再来思考,阅读下面的代码片段:

fun main(args: Array<String>) {   
    val result = 1L + 2;    
    println(result)
}

问题:这段代码可以运行吗?运行结果是多少呢?
答案是:这段代码可以运行,运行结果为3。最终,result 类型为Long。
如何理解呢?
变量 result 最终的类型是根据上下文推断出来的。代码中,存在算术运算符(我们以后会讲到),这一操作中,隐式地完成了类型转换,即:
Long + Int => Long, 算术运算符会有重载做合适的类型转换。
那么,除了算术运算符,有没有办法完成类型转换呢?
答案是肯定的,即显式转换。
在 Kotlin 中,每个数字类型都支持以下几种方式的显式转换:

  1. toByte()
  2. toShort()
  3. toInt()
  4. toLong()
  5. toFloat()
  6. toDouble()
  7. toChar()

很容易理解:toxxx(),即表示转换到xxx类型。
举个例子:我们知道,下面这段代码是无法正常运行的:

fun main(args: Array<String>){
    val intSample = 1;    
    fun doubleOutput(doubleSample: Double){        
        println(doubleSample)    
    }    
    doubleOutput(intSample)
}

但是,我们可以借助显式转换,将 intSample 转换成 Double 类型。就可以正常编译运行了!

fun main(args: Array<String>){
    val intSample = 1;    
    fun doubleOutput(doubleSample: Double){        
        println(doubleSample)    
    }    
    doubleOutput(intSample.toDouble())
}

仔细对比上面两段代码,并运行修改过的代码,其结果为:1.0,类型为 Double。

如何在ElasticSearch中的数字字段上执行全文搜索?
问答题: 如果不将数字字段转换为字符串,我该如何在其上执行全文搜索? 我正在尝试模仿_all的行为,以便在执行查询时将数字字段动态转换为字符串. 例. 建立: curl -XPUT http://loca ...
1
sql – 在varchar字段而不是数字字段上使用BETWEEN?
问答我正在使用ColdFusion 8和SQL Server 2008 R2. 我正在尝试查询一列值以获取值在一定范围内的行.该列应该是数字,但事实并非如此.它被设置为varchar(由其他人).有100 ...
sql – 将数字转换为数据类型数字的算术溢出错误
问答我每次运行此查询时始终收到此错误消息: Msg 8115, Level 16, State 8, Line 33 Arithmetic overflow error converting numeri ...
1
node.js – 数字海洋上的访问节点应用程序 – 无法访问此站点
问答我无法访问我的数字海洋节点js应用程序.我已经SSH了,从Git克隆了我的Node应用程序,安装了npm,并在Droplet上成功启动了应用程序,但是我收到了错误 This site can't be ...
在数字海洋上使用mokodb与dokku部署node.js应用程序
问答我正在尝试使用mokodb在数字海洋上使用dokku部署Node.js应用程序.不幸的是,我有一些问题让节点应用程序连接到mongodb. 到目前为止我做了什么. 我在git repo中有一个node ...
tsql – 如何在非数字字段上查询“之间”的数字数据?
问答我有一个我刚刚在数据库中找到的查询失败导致报告失败的问题.查询的基本要点: Select * From table Where IsNull(myField, '') <> '' And ...
数据集使用C#在具有Datetime数据类型的列上进行排序
问答我有一个数据集(数据集ds),下面你可以在数据集中找到包含演示数据的字段. 在我的数据集中,它们是名为Date(Datatype- DateTime)的列,我想对此列进行排序.我无法从SQl进行排序, ...
sql-server – 为什么SQL Server抛出算术溢出错误转换int到数据类型数字?
问答我运行此代码时,SQL Server Management Studio抛出一个错误: declare @percentage numeric(3,2) set @percentage = cast( ...
1
在没有uint8_t数据类型的MCU上使用uint8_t进行结构化
问答我是嵌入式软件开发人员,我想与外部设备连接.该器件通过SPI发送数据.该数据的结构是从外部设备制造商预定义的,无法编辑.制造商提供一些Header文件,其中包含通过SPI发送的所有数据的许多typed ...
ios – 如何在iPhone数字键盘上显示“完成”按钮
问答数字键盘上没有"完成"按钮.当用户在文本字段中完成输入数字信息时,如何使数字键盘消失? 我可以通过使用默认键盘得到一个"完成"按钮,但用户将不得不切换到数字键为 ...
ruby-on-rails – 在Rails 4/Capistrano/Passenger/Nginx服务器(数字海洋)上的production.log空
问答我在Ubuntu 12.04上设置了一个rails 4服务器,使用Capistrano,Nginx,Passenger,Postgres,Redis / Resque 一切都很好,除了producti ...
json – d3 – “无法在数字’65’上创建属性’vx’”
问答所以我试图将这个伟大的例子Force-Directed Graph用于一些非常简单的json:https://raw.githubusercontent.com/DealPete/forceDirec ...
javascript – 在输入数字字段上显示前导零
问答我有两个表示小时和分钟的输入字段. <input type="number" min="0" max="24" step=" ...
我应该在二进制数据类型列mysql上使用哪个索引
问答我正在编写一个简单的工具来检查重复文件(即具有相同数据的文件).机制是使用sha-512算法为每个文件生成哈希值,然后将这些哈希值存储在MYSQL数据库中.我在二进制(64)唯一非空列中存储哈希值.每 ...
sql-server-2008-r2 – SQL server 2008 R2将数值转换为数据类型数字的算术溢出错误
问答我有一个令人困惑的错误,我无法理解SQL Server 2008 R2. 但是,当我在本地服务器(也是SQL Server 2008 R2)上尝试相同的请求时,一切正常. 所以这是提出问题的请求: s ...
在数字海洋上的Ubuntu 14.04上使用Ansible设置Mesos
问答我一直在关注这个教程How to configure a production ready Mesos cluster,并且一直在创建一个安全的剧本,你可以在这里看到mesos ansible pla ...
使用数据类型的GADT上的Haskell模式匹配
问答我发现我真的很喜欢将GADT与数据类型相结合,因为它给了我更多的类型安全性(对于大多数用途,几乎和Coq一样好,Agda等).令人遗憾的是,最简单的示例中,模式匹配失败,除了类型类,我可以想象没有办法 ...
两个ggplot2数字从上到下对齐
问答我意识到ggExtra包中的align.plots函数已被弃用和删除.但是,我使用自己的版本,因为它似乎提供了我需要的特定功能.我已经研究了解决问题的方面,但我认为它不适用于我的特定问题.似乎问题是当 ...
数字列上的MySQL索引使查询速度变慢
问答我有一个相当大的表(~1.7M行)的优化问题. 选择行时会使用两列,我们称之为colA和colB.它们都是'double'类型(小数点后5位),范围从: colA:-90~90 colB:-180~1 ...
c++ 数字文字上的ULL后缀
问答我遇到了一些代码,像这样: line += addr & 0x3fULL; 显然,'U'和'L'不是十六进制数字.我猜这个十六进制数字字面值末尾的'ULL'意味着"无符号长整型&qu ...