Kotlin 学习笔记(一)基础语法、类、属性的探索

Ghyakar_ZH-CN4631836915_1920x1080.jpg

前言
本文章只是用于记录学习,所以部分地方如果有错误或者理解不对的地方,麻烦请指正。本篇为 csdn 原文章 转移修改版 原文章

工具

  1. android 开发的话 可以使用 android studio ,在新建项目的时候记得勾选 supper kotlin 就可以了,和jni 开发操作相似的。进入android studio之后如果是 3.0 以后的版本,都是自带kotlin 插件的,如果是 as3.0一下的版本则需要在 File /setting / plugins / 搜索 kotlin 安装重启。
  2. 平时跟我一样在学习的话,可以使用idea ,新建kotlin 项目,在里边联系就可以了。

1. HelloWorld 及 包的声明

在Kotlin中定义包与Java有点不同,在Kotlin中目录与包结构无需匹配,
Kotlin的源码可以在磁盘上的任意位置。

// 包格式 和 java 一致
package com.ymc.hellokotlin

fun main(args: Array<String>) {
    println("Hello world")
    println(max(2,3))
}

fun max(a:Int ,b:Int):Int{
    return if(a>b) a else b;
}

1. main 函数不需要在class 中就可以运行
2. fun 代表一个函数,后边紧跟函数名称,参数列表和返回值类型
3. 参数实现写 参数名称 然后冒号隔开,再写参数类型(和java 相反)
4. 函数的返回值是在后边的(和java刚好相反的)当然 有返回值 也可以不写返回类型(前提是:只有表达式体 函数返回类型可以省略,如果是代码块体函数就必须要 写明函数返回类型),因为kotlin 通过 类型推导 也是可以知道返回值类型的
5. system.out.println 被包装为 println
6. 在行末可以省略 分号 (类似 js)
7. 看到max函数中 if类似于三元表达式 kotlin中,if 是有结果值的表达式
8. 如果返回值 类似于 java 中的 void 则可以写成 :Unit ,当然也可以省略不写

   在kotlin 中,除了部分循环(for do 和 do/while)大多控制结构都是表达式,是有返回值的。另一方面 java 中的赋值语句为表达式,而kotlin 中则为语句。
与Java定义包名一样,在源文件的开头定义包名:但是不同的是,包名和文件夹路径可以不一致:源文件可以放在项目的任意位置,当然也不建议这样搞,自己何苦为难自己。。。

2. 变量

   考虑到kotlin 的变量声明是可以省略 类型的,所以kotlin 变量声明有别于java ,kotlin 变量声明顺序为 关键字 变量名称 类型(可不加),如果变量没有初始化 则需要明确表明 变量类型。

   常量与变量都可以没有初始化值,但是在引用前必须初始化编译器支持自动类型判断,即声明时可以不指定类型,由编译器判断。如果不在声明的时候初始化则必须提供变量的类型

val name = "ymc"
val age = 23
val age1 : Int = 23

val age2 :Int

age2 = 24

val :不可变引用 ,在val声明变量后不能再初始化之外再次赋值(java final)
var :可变引用 , 该类型变量可以随便赋值
*** 官方推荐** 尽量使用val 声明变量,使程序更接近函数式编程风格

1、可变变量的定义: var 关键字

var <变量名> : <变量类型> = <初始值>

var sum: Int = 3
sum = 8

//由于编译支持类型推导可以省略Int类型
var sum = 3
sum = 8

2、不可变变量的定义: val 关键字, 不能进行二次赋值,类似Java中的final类型

val <常量名> : <常量类型> = <初始值>

val sum: Int //没有赋值初始化之前必须指定类型
sum = 5

  已知值的属性可以使用 const 修饰符标记为 编译期常量。需要满足如下几种条件 (类似 java 中的 constanUtil 中的 常量值)

  • 位于顶层或者是 object 的一个成员
  • 用 String 或原生类型 值初始化
  • 没有自定义 getter
const val SUBSYSTEM_KEY: String = "key"

@Deprecated(SUBSYSTEM_KEY) fun foo() { …… }

3 .字符串模版

println("Hello world $name")   // $变量
println("Hello world ${age[0]}")   // ${变量}
println("Hello world " + name)   // 原来的方法也是可以继续使用的

var a = 1
a = 2
var s1 = "a is $a"
val s2 = "${s1.replace("is", "was")}, but now is $a"

4. 类和属性

 4.1 类

   接下来 我们比较一下 java 和 kotlin 中类的写法的不同

java

public class DemoBean {

    private final String name;

    public DemoBean(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

kotlin

class DemoBean(val name: String)

如果您跟我一样也是落后的kotlin初学者,我们可以在日常生活中还是以 java 语言开发为主 ,如果需要看kotlin 的效果的时候,我们可以将java 代码复制到 kt文件中,idea会自动提示我们转换。

 4.2 属性

   类 ,也就是我们将数据和处理数据的代码封装成一个单一的实体。

class Person{
    var name :String  = "ymc"    // 可读可写
    val isMarried : Boolean  = false    // 只读
}

   上段代码中 isMarried 会生成一个字段,一个getter ,而 name 则会生成 一个 getter和一个 setter 。
kotlin 在你声明属性的时候,你就声明了对应的访问器,默认的访问器 就是返回值的 getter 和 更新数值的 setter ,kotlin 会暴漏一个 getName 方法,当然我们也可以自定义访问器。

fun main(args: Array<String>) {
    var person = Person()
    println(person.name +";"+ person.isMarried )

}

   可以看到我们直接调用而不需要get,感觉很像js...

 4.3 自定义访问器

class Person{
     var name :String  = "ymc"
     var sex : Int = 0;  // 0 为女性 1为男性
     val isMarried : Boolean  = false
     val isBoy :Boolean
            get() {
                return if(sex==1) true else false
            }
}

我们将Person 添加 sex 和 isboy 属性,重写getter ,这样就可以做到自定义访问器。

如果 我们设置 属性为 val 但是通过自定义 getter 修改属性那么 属性会修改么?

fun main(args: Array<String>) {
    val name = "Hello Kotlin"
    name = "Hello Java"
}

如果单纯的 修改 则会报错

Error:(8, 5) Kotlin: Val cannot be reassigned

接下来我们通过 自定义访问器 看看

class RandomNum {
    val num: Int
        get() = Random().nextInt()
}

fun main(args: Array<String>) {
    println("the num is ${RandomNum().num}")
}

the num is -1251923160
the num is -1527833641

总结: 由以上的例子可以说明假设一是成立的,在Kotlin中的val修饰的变量不能说是不可变的,而只能说仅仅具有可读权限

 4.4 备用字段

   kotlin 中并不允许使用 字段,这个时候 我们就可以使用备用字段,比如下段 代码,起到局部变量的作用。

//初始化值会直接写入备用字段
var counter = 0 
    get() = field   // field可以理解为自己本身
    set(value) {
        if (value >= 0)
            field  = value
    }

// 这种情况并不需要备用字段,所有不会生成备用字段
val isEmpty: Boolean
    get() = this.size == 0
    

注意:field标识符只允许在属性的访问器函数内使用.

4.5 延迟初始化属性和变量

  属性声明为非空类型必须在构造函数中初始化,为处理这种情况,你可以用 lateinit 修饰符标记该属性:

public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  // 直接解引用
    }
}

  这样的话,我们就可以不用再构造函数的时候对其进行初始化,后续在哪里需要 调用 setup就可以。

5. null检查机制

Kotlin的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式,字段后加!!像Java一样抛出空异常,另一种字段后加?可不做处理返回值为 null或配合?:做空判断处理

//类型后面加 ? 表示可为空
var age: String? = "23"

//字段后面加 "!!" ,如果为null则抛出空指针异常
val ages = age!!.toInt()

//字段后面加 ”?“  如果为null不做处理返回 null
val ages1 = age?.toInt()

//使用 ”?:“  表示age为null返回-1
val ages2 = age?.toInt() ?: -1

   kotlin 中如果 数值 或 返回值可以为 空的时候 则可以在 类型后边加上 ?

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        // `obj`在这个分支中自动转换为`String`类型
        return obj.length
    }
    // `obj`仍然是`Any`类型
    return null
}

fun getStringLength(obj: Any): Int? {
    // `obj`在这个分支中自动转换为`String`类型
    if (obj !is String) return null
    return obj.length
}

   该方法返回值可以为 null 也可以是 int 类型 字符串的长度,在判断中我们有看到了新的 词语 is ,is 表达式主要检查 表达式或者值 的类型是否是 is 后边的类型,如果是 则会进行自动转换,如果不是则 仍然保持原来的数据类型。

上段代码中我们可以看到 kotlin 和 java 的类型转换的差别,java 使用instanceOf 来判断类型后,如果要转型需要 显式将该类型转换为我们比较的类型,而 kotlin 中 使用 is 检查过 数据后,如果类型正确 则会 智能转型,这一步是编译器自动帮我们完成的。
当然如果我们需要使用 显式转换的时候 可以使用 as 表达式,(val n = A as Num)

Kotlin 学习笔记(二)

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

推荐阅读更多精彩内容