Kotlin-04.基本类型/数据类型(Basic Types)

官方文档: http://kotlinlang.org/docs/reference/basic-types.html

1.介绍

与java不同,Kotlin所有数据类型都是对象,因此可在任何变量上调用成员函数和属性(字段)!

2.数字

Kotlin 处理数字在某种程度上接近 Java,但是并不完全相同。
例如,对于数字没有隐式把范围变宽转换(如在 Java 中 int 可以隐式转换为long),
另外有些情况的字面值略有不同。

Kotlin 内置数字类型:
    类型    位数
    Double  64
    Float   32
    Long    64
    Int     32
    Short   16
    Byte    8
注意在 Kotlin 中字符Char不能转化为数字

3.数值字面常量

数值常量字面值表示:
    十进制:   123        
    十六进制: 0x0F
    二进制:   0b00001011
    注意: 不支持八进制(而java以0开头表示八进制 07)

    Long 用大写 L 标记:    123L  
    Float 用 f 或 F 标记:  123.5f
    double:              123.5、123.5e10

自 Kotlin 1.1 起,用下划线使数字更易读:   
    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

4.数字自动装箱-表示方式

Kotlin数字在虚拟机中是物理存储为JVM原生类型,但如果是可null引用(有问号?)或者泛型对象,
那么kotlin数字就会自动装箱(类似java包装类,如int自动装箱转为Integer)

kotlin数字自动装箱的实例:
    val a: Int = 10000       
    val boxA: Int? = a //有问号? 会自动装箱
    val boxB: Int? = a //有问号? 会自动装箱

kotlin三个等号===比较的是对象地址(引用),自动装箱会生成新对象,两个对象不同,输出false
但是数值在-128和127之间时,自动装箱会重用同一个对象(java缓存机制),输出true
    print(boxA === boxB) //输出false,如果数值在-128和127之间,输出true

kotlin两个等号==比较的是对象数值,两个对象数值相同,输出true
    print(boxA == boxB) //输出true

5.显式转换

范围较小数字类型不能隐式转换为范围较大类型。
    val b: Byte = 1 // 正确, 字面值是静态检测的
    val i: Int = b // 错误: 隐式扩宽
    val i: Int = b.toInt() // 正确: 显式扩宽

每个数字类型支持如下类型转换:
    toByte(): Byte
    toShort(): Short
    toInt(): Int
    toLong(): Long
    toFloat(): Float
    toDouble(): Double
    toChar(): Char

缺少隐式扩宽转换是很少引人注意的,因为类型是从上下文推断出来的,而算术运算会有重载做适当扩宽转换,例如:
    val l = 1L + 3 // Long + Int => Long

6.位运算

Kotlin支持数字运算的标准集,运算被定义为相应的类成员(但编译器会将函数调用优化为相应的指令)
对于按位运算,没有特殊字符来表示,而只可用中缀方式调用函数,例如:
    val x = (1 shl 2) and 0x000FF000
以下是完整位运算列表(只用于 Int 和 Long):
    shl(bits) – 有符号左移 (Java 的 <<)
    shr(bits) – 有符号右移 (Java 的 >>)
    ushr(bits) – 无符号右移 (Java 的 >>>)
    and(bits) – 位与
    or(bits) – 位或
    xor(bits) – 位异或
    inv() – 位非

7.字符

字符用 Char 类型表示,不能直接当作数字
    fun check(c: Char) {
        if (c == 1) { // 错误:类型不兼容
            // ……
        }
    }
字符字面值用单引号括起来: '1' 
特殊字符可以用反斜杠转义: \t、 \b、\n、\r、\'、\"、\\ 和 \$。 
编码其他字符用 Unicode 转义序列语法:'\uFF00'。

我们可以显式把字符转换为 Int 数字
fun decimalDigitValue(c: Char): Int {
    if (c !in '0'..'9')
        throw IllegalArgumentException("Out of range")
    return c.toInt() - '0'.toInt() // 显式转换为数字
}
当需要可null引用时,像数字一样,字符也会被装箱。
装箱操作不会保留同一性(同一对象)。

8.布尔

布尔用 Boolean 类型表示,它有两个值:true 和 false。
若需要可空引用布尔会被装箱。

9.数组

数组在 Kotlin 中使用 Array 类来表示,它定义了 get 和 set 函数(按照运算符重载约定转变为 [])和 size 属性

使用库函数 arrayOf() 来创建一个数组并传递元素值
    arrayOf(1, 2, 3) 创建了 array [1, 2, 3]
或  arrayOfNulls() 创建一个指定大小的null数组

使用接受数组大小和一个函数参数的工厂函数,用作参数的函数能够返回每个元素初始值:
    // 创建一个 Array<String> 初始化为 ["0", "1", "4", "9", "16"]
    val asc = Array(5, { i -> (i * i).toString() })

注意: 与 Java 不同的是,Kotlin 中数组是不型变的(invariant)。
这意味着 Kotlin 不让 Array<String> 赋值给 Array<Any>,以防止可能的运行时失败(但是可用 Array<out Any>)

还有无装箱开销的类表示原生类型数组: ByteArray、 ShortArray、IntArray 等等,这些类和 Array 并没有继承关系,但是有同样方法属性,相应的工厂方法
    val x: IntArray = intArrayOf(1, 2, 3)
    x[0] = x[1] + x[2]

10.字符串

字符串用 String 类型表示,字符串是不可变的;
字符串元素可通过索引操作 s[i]
可用 for 循环迭代字符串:
    for (c in str) {
        println(c)
    }

1.字符串字面值

Kotlin 有两种类型的字符串字面值: 
一是转义字符串 可以有转义字符,二是原始字符串 可以包含换行和任意文本

转义字符串 很像 Java 字符串:
    val s = "Hello, world!\n"
    转义采用传统的反斜杠方式

原始字符串 使用三个引号 """ 括起来,
内部没有转义并且可以包含换行和任何其他字符:
    val text = """
        for (c in "foo")
            print(c)
    """

你可以通过 trimMargin() 函数去除前导空格:
val text = """
    |Tell me and I forget.
    |Teach me and I remember.
    |Involve me and I learn.
    |(Benjamin Franklin)
    """.trimMargin()
默认 | 用作边界前缀,可用其他字符作为参数传入 trimMargin(">")

2.字符串模板

字符串可以包含模板表达式 ,即一些小段代码,会求值并把结果合并到字符串中。 
模板表达式以美元符 $ 开头

由一个简单变量构成:
    val i = 10
    val s = "i = $i" // 求值结果为 "i = 10"

用花括号{任意表达式}:
    val s = "abc"
    val str = "$s.length is ${s.length}" // 求值结果为 "abc.length is 3"

原始字符串和转义字符串内都支持模板。 
如果你需要在原生字符串中表示字面值 $ 字符(不支持反斜杠转义):
    val price = """
                ${'$'}9.99
                """

简书: http://www.jianshu.com/p/084dec2793dc
优快云博客: http://blog.youkuaiyun.com/qq_32115439/article/details/73196341
GitHub博客: http://lioil.win/2017/06/13/Kotlin-basic-types.html
Coding博客: http://c.lioil.win/2017/06/13/Kotlin-basic-types.html

<think>我们遇到了一个Gradle构建失败的问题,错误信息是: > Kotlin metadata version mismatch: expected 1.7.1 but found 1.9.0 这个错误通常是由于项目中使用的Kotlin相关库或插件的版本不一致导致的。具体来说,编译时使用的Kotlin编译器版本(1.7.1)与某个依赖库的元数据版本(1.9.0)不匹配。 ### 解决步骤 #### 1. 统一Kotlin版本 首先,确保项目中所有Kotlin相关组件的版本一致。在项目的根`build.gradle`(或`build.gradle.kts`)中,设置统一的Kotlin版本。 **示例(Kotlin DSL)**: ```kotlin // 项目根目录的 build.gradle.kts buildscript { // 设置Kotlin版本 val kotlinVersion = "1.9.0" dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") // 其他classpath } } allprojects { // 确保所有子项目使用相同的Kotlin版本 configurations.all { resolutionStrategy { eachDependency { if (requested.group == "org.jetbrains.kotlin") { useVersion(kotlinVersion) } } } } } ``` #### 2. 检查Gradle插件版本 确保Android Gradle插件(AGP)与Kotlin版本兼容。参考官方兼容性文档:[Kotlin与AGP的兼容性](https://developer.android.com/studio/releases#agp_versions) 例如,AGP 8.0.0以上版本需要Kotlin 1.8.0以上。 #### 3. 清理构建 在修改版本后,执行清理构建: ```bash ./gradlew clean ./gradlew --stop # 停止守护进程 ./gradlew assembleDebug --stacktrace ``` #### 4. 检查依赖冲突 如果问题仍然存在,可能是某个依赖引入了不兼容的Kotlin库。使用以下命令检查依赖树: ```bash ./gradlew app:dependencies --configuration compileClasspath ``` (将`app`替换为你的模块名) 在输出中查找不兼容的Kotlin库(如`kotlin-stdlib`、`kotlin-reflect`等),然后通过排除或强制指定版本解决。 **示例**: ```kotlin dependencies { implementation("some.library:1.0") { exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib") } // 或者强制指定版本 implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") } ``` #### 5. 更新Kotlin元数据 如果依赖库的Kotlin元数据版本过高,而你的项目暂时不能升级Kotlin版本,可以尝试在`gradle.properties`中添加: ``` kotlin.mpp.enableCompatibilityMetadataVariant=true ``` 这个选项允许使用不同元数据版本的库共存,但可能不是长久之计,建议升级Kotlin版本。 ### 常见原因 - **多模块项目版本不一致**:确保所有模块使用相同的Kotlin版本。 - **过时的第三方库**:某些库可能依赖于旧版Kotlin,尝试更新这些库或联系维护者。 ### 验证 构建成功后,检查构建输出中Kotlin相关库的版本是否统一。 §§相关问题§§ 1. 如何查看项目中Kotlin库的当前版本? 2. Gradle依赖冲突的解决方法有哪些? 3. Kotlin版本升级需要注意哪些问题?</think>### 解决 Kotlin 元数据版本不匹配错误 错误信息 `Kotlin metadata version mismatch expected 1.7.1 but found 1.9.0` 表示项目中的 Kotlin 组件版本不一致。以下是完整解决方案: --- ### 核心解决步骤 #### 1. **统一 Kotlin 版本** 在根项目的 `build.gradle.kts` 中强制统一版本: ```kotlin // 根目录 build.gradle.kts allprojects { configurations.all { resolutionStrategy { force("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") force("org.jetbrains.kotlin:kotlin-reflect:1.9.0") force("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0") } } } ``` #### 2. **更新插件版本** 在模块的 `build.gradle.kts` 中显式指定版本: ```kotlin plugins { kotlin("android") version "1.9.0" // 强制对齐版本 id("com.android.application") version "8.1.0" } ``` #### 3. **清理构建缓存** ```bash ./gradlew cleanBuildCache ./gradlew --stop # 停止所有Gradle守护进程 rm -rf ~/.gradle/caches # 删除全局缓存(谨慎操作) ``` --- ### 依赖冲突排查 #### 1. 检查依赖树 ```bash ./gradlew :app:dependencies --scan > deps.txt ``` 在输出文件中搜索 `kotlin-stdlib`,确认是否存在多个版本。 #### 2. 排除冲突依赖 ```kotlin dependencies { implementation("com.example:library") { exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib") } implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") } ``` --- ### 版本兼容性矩阵 | 组件 | 要求版本 | 解决方案 | |------|----------|----------| | Kotlin Gradle 插件 | 1.9.0 | 显式声明 `kotlin-gradle-plugin` 版本 | | Kotlin 标准库 | 1.9.0 | 通过 `force()` 强制统一 | | Android Gradle 插件 | ≥8.0.0 | 升级至 AGP 8.1.0 | --- ### 验证修复 在 `gradle.properties` 添加: ```properties kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.native.enableDependencyPropagation=false ``` 执行构建并检查日志: ```bash ./gradlew assembleDebug --stacktrace | grep -i "kotlin" ``` 成功标志:**不再出现 `version mismatch` 错误**。 --- ### 根本原因分析 此错误通常由以下原因导致: 1. **多模块版本不一致**:子模块使用不同 Kotlin 版本 2. **传递依赖冲突**:第三方库引入旧版 Kotlin 库 3. **缓存污染**:旧版元数据残留在 Gradle 缓存中 > **提示**:长期解决方案是迁移到 Kotlin 1.9.0+ 并统一所有模块的 BOM 管理[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值