Kotlin 数据之本变量

变量和常量用来存储数据和传递数据,类型则用来描述变量和常量保存的是什么样的数据类型。

数据类型

变量和常量都有数据类型,数据类型用来描述变量和常量保存的数据,告诉编译器该如何进行类型检查。理论结合实践,我们创建一个新项目,项目名,VarType(变量类型)。

使用IntelliJ创建新项目

第一次打开IntelliJ集成开发环境,点击New Project


选择Kotlin,选择 JVM | IDEA,表示用Java JVM 开发Kotlin编程。


点击Next,如图


最后点击Finish,项目创建完成。


右键src,选择New,选择Kotlin File/Class


选择File,输入TypeIntro,按下回车后新文件会在编辑器中打开。

输入main函数

fun main() {
    
}

变量声明

在TypeIntro中创建一个apple变量,表示有6个苹果

fun main() {
    var apple: Int = 6  // 有6 个苹果
    println(apple)  // 打印苹果变量值到控制台
}

上述代码中,将一个Int类型值赋给了apple。var关键字定义了一个变量。var 后面跟着变量名,便是你想定义一个新变量。使用:Int 指定变量的类型,:Int变量表明apple要存储的是整数。使用赋值运算符(=) 把右边的实例值6赋值给左边的apple。 // 代表注释,会完全忽略注释

变量定义的图解


定义变量并赋值,接下来使用println函数将变量值输出到控制台。


现在,尝试将apple 变量赋值 "red"

我们看到有一个红色的波浪线,编译器说字符串实例不能赋值给Int类型。我们把鼠标放到红色的波浪线上,会有一个错误提示弹框。我们输入的每一个字符,每一行代码,都在和编译器沟通,编译器一直在做语法检查。确保每行代码都符合语法要求!就像我们学习英语的时候,语法决定了语句的正确性!

为了改正错误类型,我们将apple实例值改为5。

fun main() {
    var apple: Int = 5
    println(apple)
}

班里现在有10哥同学,5个苹果不够吃,我们在增加5个苹果。

fun main() {
    var apple: Int = 5
    apple += 5
    println(apple)
}

现在我们总共有了10个苹果,运行代码,看看结果

我们先来看看最常用的类型

类型 描述 示例
String 字符串 "Apple"
char 单字符 'X'
Int 整数 6
Boolean true/false值 true
Double 小数 3.14
List 元素集合 1,2,4
Set 无重复元素结合 "Hello" "WOrld"
Map 键值对 "apple" to 6,"banana" to "8"

只读变量

前面你已经看到,变量可以重新赋值。但通常我们也需要不能在重新赋值的变量。例如,丈夫的工资都在媳妇的银行卡里,媳妇给了丈夫每天60元生活费,除此之外丈夫身无分文,媳妇不希望丈夫有更多的钱,我们来定义一个丈夫的生活费变量。

fun main() {
    var apple: Int = 5
    apple += 5
    println(apple)
    val husbandExpense  = 60   // 媳妇定义了丈夫每天60元的生活费,媳妇不希望丈夫有更多的钱
    husbandExpense +=100     // 丈夫想要更多的钱,那是不可能地,你会发现这行代码出错了
    println(husbandExpense)
}

只读变量只能在定义时赋初值,以后不能在改它的值。我们注释掉丈夫生活费增加100元的那行代码,如下所示:

现在运行代码,看看输出结果

10
60

Process finished with exit code 0

编译器在我们输入代码时,能判定可变变量和只读变量是否运用恰当。如果一个不可变变量使用了var 关键字,编译器会提示我们改为val。我们只要有必要,都建议使用 val 关键字。

类型推断

注意看上面的代码,只读变量 husbandExpense 我们没有加变量类型,编译器使用了类型推断。对于以声明并赋值的变量,编译器清楚的知道这个变量的类型是什么。它允许你省略类型定义!
我们再注意看一开始定义的 apple 可变变量,:Int是灰色的,编译器说类型定义是多余的,对于以声明并赋值的变量,已经精确的给出了类型,这就是Kotlin的自动类型推断。
单击 apple 变量旁边的Int 类型定义,然后按下(Alt + Enter)组合键,如图

按下回车键,IntelliJ 能够自动帮你删除冗余的代码。可以看到 Int 类型定义不见了。我们以后编写代码都不会明确指定变量的类型,除非有歧义,这样的代码编写的更简洁!

我们按下 Ctrl + Shift + P 组合键,IntelliJ 会自动显示出变量的类型。

编译时常量

编译时常量只能在函数之外定义,只是因为编译时常量,只能在编译时赋值,而main函数和其它函数都是在运行时才调用。函数内的变量也是在那是赋值的。
因为使用复杂的数据类型可能会危害编译时的安全保障,所以编译时常量只能是一些常见的基本数据类型。基本数据类型我们很快就会全部学完。
使用const 修饰符定义一个编译时常量

//媳妇很坚定的说,你每天最多只有60元生活费,而且这辈子我说了算
const val MAX_EXPENSE: Int = 60
fun main() {
  
}

MAX_EXPENSE 由 const 和 val 修饰符一起告诉编译器,MAX_EXPENSE 常量值绝不会改变。这也就是说,整数值60要绝对保证不变。编译器就知道如何灵活处理代码。

对 MAX_EXPENSE 的书写格式感到好奇吗?没错,为了凸显编译时常量,我们都是这么写的。

前面不是有只读变量吗,为什么要加编译时常量呢!因为只读变量不能保证变量一定不能修改。

常量Kotlin 字节码,看下图

熟悉Java 的朋友阅读起来很熟悉,不熟悉Java的朋友做个参数

import kotlin.Metadata;

@Metadata(
   mv = {1, 1, 16},
   bv = {1, 0, 3},
   k = 2,
   d1 = {"\u0000\u000e\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0002\u001a\u00020\u0003\"\u000e\u0010\u0000\u001a\u00020\u0001X\u0086T¢\u0006\u0002\n\u0000¨\u0006\u0004"},
   d2 = {"MAX_EXPENSE", "", "main", "", "VarType"}
)
public final class TypeIntroKt {
   public static final int MAX_EXPENSE = 60;

   public static final void main() {
      int apple = 5;
      int apple = apple + 5;
      boolean var1 = false;
      System.out.println(apple);
      int husbandExpense = 60;
      boolean var2 = false;
      System.out.println(husbandExpense);
   }

   // $FF: synthetic method
   public static void main(String[] var0) {
      main();
   }
}

我们发现Kotlin源码中定义的 Int 引用数据类型,翻译成Java源码后是基本数据类型。Kotlin 没有基本数据类型,Kotlin 编译器会根据情况,将引用数据类型编译成基本数据类型,以提高代码的性能。Kotlin在背后为我们做了许多事情,背后的故事我们来看两个变量。注意观察 apple 变量 和 husbandExpense 变量的定义:

    var apple = 5
    val husbandExpense = 60

在Kotlin 源码中,我们已经省略了变量类型的定义,但在字节码中,我们反编译字节码,得到Java代码,还是看到它们的显示类型定义。由此可见,字节码讲述了背后的故事,即Kotlin支持类型推断,所以不像Java那样,需要显示指定变量类型定义。

我们在这里学习了可变变量和只读变量存储基本数据,知道何时改用哪种变量。这主要取决于变量值是否能修改;了解了如何使用编译时常量定义不可变变量;学会了使用Kotlin自动类型推断,在声明时简化代码书写。后面我们会反复用到这些知识。下一章我们将学习条件语句,写一个简单的计算器。

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