返回顶部
首页 > 资讯 > 移动开发 >Kotlin基础学习-入门篇
  • 718
分享到

Kotlin基础学习-入门篇

kotlinandroid 2023-09-07 07:09:12 718人浏览 独家记忆
摘要

本篇文章来自郭霖大佬的第一行代码中的Kotlin教程,笔者只是在学习Kotlin过程中记录学习过程。 Kotlin系列已更新: Kotlin基础学习-入门篇 Kotlin基础学习-第二篇 Kotli

本篇文章来自郭霖大佬的第一行代码中的Kotlin教程,笔者只是在学习Kotlin过程中记录学习过程。

Kotlin系列已更新:

Kotlin基础学习-入门篇

Kotlin基础学习-第二篇

Kotlin进阶学习-第三篇

Kotlin进阶学习-第四篇

Kotlin进阶学习-第五篇

文章目录

kotlin的历史

Kotlin由JetBrains公司开发设计,2011年公布第一版,2012年开源

2016年发布1.0正式版,并且JetBrainsidea加入对Kotlin的支持,安卓自此又有新的选择。

2019年谷歌宣布Kotlin成为安卓第一开发语言,安卓程序员javaKotlin已经迫在眉睫。

Kotlin的工作原理

语言分为解释型和编译型两种

语言类型

编译型

编译器直接将源代码一次性编译成二进制文件,计算机可直接执行,例如C,c++

优点:一次编译,即可运行,运行期不需要编译,运行效率高。

缺点:不同操作系统需要不同的机器码,且修改代码需要真个模块重新编译

解释型

程序运行时,解释器会将源码一行一行实时解析成二进制再执行。例如jspython

优点:平台兼容性好,安装对应的虚拟机即可运行。

缺点:运行时需要解释执行,效率较低。

Java的语言类型

java准确来说属于混合型语言,但更偏向于解释型。

编译java存在JITAOTJIT即时编译将可将热点代码直接编译成机器码,AOT预先编译可再安装时把代码编译成机器码

解释java运行时需编译成class文件,java虚拟机再解释执行.class

Kotlin的运行原理

java虚拟机只认class文件, 虚拟机不会关心classjava文件编译来的,还是其他文件编译来的。那此时我们创造一套自己的语法规则,再做一个对应的编译器,,则可让我们的语言跑在java虚拟机上。Kotlin则是此原理,运行前会先编译成class,再供java虚拟机运行。

创建Kotlin项目

打开Android studio,在选择语言时,选择Kotlin

在包下创建kotlin文件

创建File命名为HelloWorld

敲入下面代码则可运行打印Hello World!

package com.hbsd.demofun main() {    println("Hello World!")}

运行结果如下:

下面进入语法学习

语法

变量

变量的声明

Kotlin使用var,val来声明变量,注意:Kotlin不再需要;来结尾

var 可变变量,对应java非final变量

var b = 1

val不可变变量,对应javafinal变量

val a = 1

两种变量并未声明类型,这是因为Kotlin存在类型推导机制,上述的a,b会默认为Int。假设想声明具体类型,则需下面的方式

var c: Int = 1

基本类型

Kotlin不再存在基本类型,将全部使用对象类型

Java基本类型Kotlin对象类型对象类型说明
intInt整型
longLong长整型
shortShort短整型
floatFloat单精度浮点型
doubleDouble双精度浮点型
booleanBoolean布尔型
charChar字符型
byteByte字节型

var和val的本质区别

打开Kotlin对应的Java文件

再点击下方按钮

则可查看对应的Java文件

public final class HelloWorldKt {    private static final int a = 1;    private static int b = 2;    private static int c = 10;        ...}

发现val a对应的为finalvar bvar c 对应的为非final

Kotlin此设计的原因则是防止非final的滥用,若一个变量永远不被修改则有必要给其加上final,使其他人看代码时更好理解。

后期我们写代码时则可先使用val,若真的需要修改再改为var

函数

函数的声明

无参无返回值

fun test() {}

有参有返回值

参数的类型需要写在形参名后面中间使用:连接多个参数使用,分割",“返回值使用”:"拼接

fun add(a: Int, b: Int): Int {    return a + b}

声明技巧

当函数体只有一行代码时可直接使用下面方式声明方法

fun add (a: Int, b: Int): Int = a + b 

Kotlin存在类型推导,返回值类型也可省略

fun add (a: Int, b: Int) = a + b

函数的调用

fun main() {    test()    println(add(1, 2))}//运行结果//test//3

if语句

Kotlin中的选择控制有两种方式。ifwhen

if

Javaif区别不大,实现一个返回最大值的函数

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

Kotlin的if可以包含返回值,if语句的最后一行会作为返回值返回

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

上述我们说过一行代码可省略返回值

fun max(a: Int, b: Int) = if (a > b) a else b

查看对应的Java文件,其上述实现都与下面代码等价

public static final int max(int a, int b) {   return a > b ? a : b;}

when

实现一个查询成绩的函数,用户传入名字,返回成绩级别

if实现

Kotlinif语句必须要有else,不然会报错

fun getScore(name: String) = if (name == "Tom") "不及格"else if (name == "Jim") "及格"else if (name == "Pony") "良好"else if (name == "Tony") "优秀"else "名字非法"

Kotlin==等价于Javaequals比较的时是对象里的内容, === 等价于Java==,比较的为对象的引用。

when实现

也必须实现else,否则报错

fun getScore(name: String) = when(name) {    "Tom" -> "不及格"    "Jim" -> "及格"    "Pony" -> "良好"    "Tony" -> "优秀"    else -> "名字非法"}

when支持参数检查

fun checkNumber(num: Number) {    when (num) {        is Int -> println("Int")        is Double -> println("Double")        else -> println("others")    }}

when可不传递形参

使用Boolean使when更加灵活

fun getScore(name: String) = when {    name == "Tom" -> "不及格"    name == "Jim" -> "及格"    name == "Pony" -> "良好"    name == "Tony" -> "优秀"    else -> "名字非法"}

-> 后不仅可以只执行一行代码,可以多行,看一个比较复杂的例子:

fun getScore(name: String) = when {    //若name以Tom开头则命中此分支    name.startsWith("Tom") -> {        //处理        println("你好,我是Tom开头的同学")        "不及格"    }    name == "Jim" -> "及格"    name == "Pony" -> "良好"    name == "Tony" -> "优秀"    else -> "名字非法"}

循环语句

Kotlin有两种循环方式,whilefor-inwhilejava中的while没有区别,for-in是对Java for-each的加强,Kotlin舍弃了for-i的写法

while不再赘述,在学习for-in之前需要明确一个概念-区间

val range = 0..10 //区间代表[0,10]

for-in需借助区间来使用

fun main() {    val range = 0..10    for (i in range) { //也可直接for (i in 0..10)        println(i)    }    //输出结果为 从0打印到10}

0..10 代表双闭区间,如果想使用左闭右开呢,需要借助until关键字

fun main() {    for (i in 0 until 10) {        println(i)    }    //输出结果为 从0打印到9}

上述实现是逐步进行相当于i++Kotlin也支持跳步

fun main() {    for (i in  0 until 10 step 2) {        println(i)    }    //输出结果为0,2,4,6,8}

上述实现都是升序,Kotlin也可降序循环

fun main() {    for (i in  10 downTo 1) {        println(i)    }    //输出结果为10 - 1}

for-in不仅可对区间进行遍历,还可对集合进行遍历,后续在集合处进行展示。

类和对象

类的创建和对象的初始化

在创建页面选择Class创建

创建Person类,并声明nameage,创建printInfo方法

class Person {    var name = ""    var age = 0    fun printInfo() {        println(name +"'s age is " + age)    }}

main方法中声明一个Person对象并调用printInfo方法

fun main() {    val person = Person()    person.name = "zjm"    person.age = 20    person.printInfo()}//结果如下zjm's age is 20

继承

声明Student类继承PersonKotlin中继承使用**:**,后接父类的构造,为什么需要构造后续讲解

class Student : Person(){ //此时Person报错    var number = ""    var grade = 0    fun study() {        println(name + "is studying")    }}

Person类当前不可继承,查看Person对应的java文件

public final class Person {    ...}

Person类为final不可被继承,因此需借助open关键字

只需在Person类前加上open

open class Person {...}

此时Personjava文件变为

public class Person {...}

此时Student将不再报错

构造

构造分为主构造和此构造

主构造

主构造直接写在类后面

修改Student

class Student(val number: String, val grade: Int) : Person(){...}

在创建Student对象时,如下创建

val student = Student("1234", 90)

因之前Person还有nameage,下面修改Person类的主构造

open class Person(val name: String, val age: Int) {    ...}

此时Student报错,因为继承Person时,后边使用的是Person()无参构造,上面我们修改了Person的构造,则不存在无参构造了。

再修改Student

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age){   ...}

此时不在报错,声明方式如下

val student = Student("zjm", 20, "1234", 90)

在构造时需要进行特殊处理怎么办,Kotlin提供了init结构体,主构造的逻辑可在init中处理

open class Person(val name: String, val age: Int) {    init {        println("name is" + name)        println("age is" + age)    }}

上述修改都为主构造,那如果类想有多个构造怎么办,此时需借助次构造

次构造

此时实现Student的另外两个构造

三个参数的构造,nameagenumbergrade不传参默认为``0

无参构造,字符串默认为"",int默认为0

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age){    constructor(name: String, age: Int, number: String) : this(name, age, number, 0) {            }    constructor() : this("", 0, "", 0) {            }    ...}

创建如下:

fun main() {    val student1 = Student("zjm", 20, "123", 90)    val student2 = Student("zjm", 20, "123")    val student3 = Student()}

无主构造

若类不使用主构造,则后续继承类也不需要使用构造即可去掉继承类的(),次构造可以调用父类构造super进行初始化,但是次构造的参数在其他地方无法引用

class Student : Person {    constructor(name: String, age: Int, number: String) : super(name, age) {    }fun study() {        //name,age可使用        println(name + "is studying")        //使用number则会报错,若number是主构造的参数则可引用        //println(number) 报红    }}

接口

接口的定义

Java中的接口定义类似

interface Study {    fun study()    fun readBooks()    fun doHomework()}

接口的继承

继承接口只需在后用","拼接,需实现Study声明的全部函数

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age), Study{        ...    override fun study() {        TODO("Not yet implemented")    }    override fun readBooks() {        TODO("Not yet implemented")    }    override fun doHomework() {        TODO("Not yet implemented")    }}

Kotlin支持接口方法的默认实现,jdk1.8以后也支持此功能,方法有默认实现则继承类无需必须实现此方法

interface Study {    fun study() {        println("study")    }    fun readBooks()    fun doHomework()}

权限修饰符

JavaKotlin的不同如下表所示:

修饰符JavaKotlin
public所有类可见所有类可见(默认)
private当前类可见当前类可见
protected当前类,子类,同包下类可见当前类,子类可见
default同包下类可见(默认)
internal同模块下的类可见

Kotlin引入internal,摒弃了default

使用:

类上

public open class Person(val name: String, val age: Int){...}

变量上

private val value = 1

方法上

private fun test() {    }

数据类和单例类

数据类

数据类则只处理数据相关,与Java Bean类似,通常需要实现其getsethashCodeequalstoString等方法

下面实现UserBean,包含idnamepwd属性

Java编写入如下:

public class UserBean {    private String id;    private String name;    private String pwd;    public UserBean() {    }    public UserBean(String id, String name, String pwd) {        this.id = id;        this.name = name;        this.pwd = pwd;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        UserBean userBean = (UserBean) o;        return Objects.equals(id, userBean.id) && Objects.equals(name, userBean.name) && Objects.equals(pwd, userBean.pwd);    }    @Override    public int hashCode() {        return Objects.hash(id, name, pwd);    }    @Override    public String toString() {        return "UserBean{" +                "id='" + id + '\'' +                ", name='" + name + '\'' +                ", pwd='" + pwd + '\'' +                '}';    }    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPwd() {        return pwd;    }    public void setPwd(String pwd) {        this.pwd = pwd;    }}

Kotlin编写此类将变得非常简单,新建一个kt文件,选择如下:

一行代码即可搞定,Kotlin会自动实现上述方法。

data class UserBean(val id: String, val name: String, val pwd: String)

若无data关键字,上述方法(hashCodeequalstoString)无法正常运行,去掉data查看Kotlin对应的java文件:

public final class UserBean {   @NotNull   private final String id;   @NotNull   private final String name;   @NotNull   private final String pwd;   @NotNull   public final String getId() {      return this.id;   }   @NotNull   public final String getName() {      return this.name;   }   @NotNull   public final String getPwd() {      return this.pwd;   }   public UserBean(@NotNull String id, @NotNull String name, @NotNull String pwd) {      Intrinsics.checkNotNullParameter(id, "id");      Intrinsics.checkNotNullParameter(name, "name");      Intrinsics.checkNotNullParameter(pwd, "pwd");      super();      this.id = id;      this.name = name;      this.pwd = pwd;   }}

发现上面代码既无hashCodeequalstoString也无set

加上data且把变量改为var,对应的java文件如下:

public final class UserBean {   @NotNull   private String id;   @NotNull   private String name;   @NotNull   private String pwd;   @NotNull   public final String getId() {      return this.id;   }   public final void setId(@NotNull String var1) {      Intrinsics.checkNotNullParameter(var1, "");      this.id = var1;   }   @NotNull   public final String getName() {      return this.name;   }   public final void setName(@NotNull String var1) {      Intrinsics.checkNotNullParameter(var1, "");      this.name = var1;   }   @NotNull   public final String getPwd() {      return this.pwd;   }   public final void setPwd(@NotNull String var1) {      Intrinsics.checkNotNullParameter(var1, "");      this.pwd = var1;   }   public UserBean(@NotNull String id, @NotNull String name, @NotNull String pwd) {      Intrinsics.checkNotNullParameter(id, "id");      Intrinsics.checkNotNullParameter(name, "name");      Intrinsics.checkNotNullParameter(pwd, "pwd");      super();      this.id = id;      this.name = name;      this.pwd = pwd;   }   @NotNull   public final String component1() {      return this.id;   }   @NotNull   public final String component2() {      return this.name;   }   @NotNull   public final String component3() {      return this.pwd;   }   @NotNull   public final UserBean copy(@NotNull String id, @NotNull String name, @NotNull String pwd) {      Intrinsics.checkNotNullParameter(id, "id");      Intrinsics.checkNotNullParameter(name, "name");      Intrinsics.checkNotNullParameter(pwd, "pwd");      return new UserBean(id, name, pwd);   }   // $FF: synthetic method   public static UserBean copy$default(UserBean var0, String var1, String var2, String var3, int var4, Object var5) {      if ((var4 & 1) != 0) {         var1 = var0.id;      }      if ((var4 & 2) != 0) {         var2 = var0.name;      }      if ((var4 & 4) != 0) {         var3 = var0.pwd;      }      return var0.copy(var1, var2, var3);   }   @NotNull   public String toString() {      return "UserBean(id=" + this.id + ", name=" + this.name + ", pwd=" + this.pwd + ")";   }   public int hashCode() {      String var10000 = this.id;      int var1 = (var10000 != null ? var10000.hashCode() : 0) * 31;      String var10001 = this.name;      var1 = (var1 + (var10001 != null ? var10001.hashCode() : 0)) * 31;      var10001 = this.pwd;      return var1 + (var10001 != null ? var10001.hashCode() : 0);   }   public boolean equals(@Nullable Object var1) {      if (this != var1) {         if (var1 instanceof UserBean) {            UserBean var2 = (UserBean)var1;            if (Intrinsics.areEqual(this.id, var2.id) && Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.pwd, var2.pwd)) {               return true;            }         }         return false;      } else {         return true;      }   }}

此时则和手动编写的java bean功能一样了,所有方法都可正常运行

单例类

目前Java使用最广的单例模式的实现如下:

public class Singleton {    private Singleton() {    }        private static class SingletonHolder {        private static final Singleton INSTANCE = new Singleton();    }        public static Singleton getInstance() {        return SingletonHolder.INSTANCE;    }    public void test() {        ...    }}

Kotlin中创建单例类需选择Object

生成代码如下:

object Singleton {    fun test() {        ...    }}

其对应的java文件如下,和上述使用最多的java单例实现类似

public final class Singleton {   @NotNull   public static final Singleton INSTANCE;   public final void test() {   }   private Singleton() {   }   static {      Singleton var0 = new Singleton();      INSTANCE = var0;   }}

使用如下:

fun main() {    Singleton.test() //对应的java代码为Singleton.INSTANCE.test();}

Lambda

许多高级语言都支持Lambdajavajdk1.8以后才支持Lamda语法,LamdaKotlin的灵魂所在,此小节对Lambda的基础进行学习,并借助集合练习。

集合的创建和遍历

List

fun main() {    //常规创建    val list = ArrayList<Int>()    list.add(1)    list.add(2)    list.add(3)        //listOf不可变,后续不可添加删除,只能查    val list1 = listOf<Int>(1, 2, 3 ,4 ,5)    list1.add(6)//报错        //mutableListOf,后续可添加删除    val list2 = mutableListOf<Int>(1, 2, 3 ,4 ,5)    list2.add(6)        //循环    for (value in list2) {        println(value)    }}

Set

set用法与List类似,只是把listOf替换为mapOf

Map

fun main() {    val map = HashMap<String, String>()    map.put("1", "zjm")    map.put("2", "ljn")    //Kotlin中map支持类似下标的赋值和访问    map["3"] = "lsb"    map["4"] = "lyx"    println(map["2"])    println(map.get("1"))    //不可变    val map1 = mapOf<String, String>("1" to "zjm", "2" to "ljn")    map1["3"] = "lsb" //报错        //可变    val map2 = mutableMapOf<String, String>("1" to "zjm", "2" to "ljn")    map2["3"] = "lsb"        for ((key, value) in map) {        println(key + "   " + value)    }    }

Lambda的使用

方法在传递参数时都是普通变量,而Lambda可以传递一段代码

Lambda表达式的语法结构

{参数名1: 参数类型, 参数名2:参数类型 -> 函数体}

Kotlinlist提供了maxByOrNull函数,返回当前list中xx最大的元素,XX是我们定义的条件,可能为长度,可能是别的,我们拿长度举例。

若不使用maxBy,实现如下

fun main() {    val list = listOf<String>("a", "aba", "aabb", "a")    var maxStr = ""    for (str in list) {        if (str.length > maxStr.length) {            maxStr = str;        }    }    println(maxStr)}

maxByOrNull是一个普通方法,需要一个Lambda参数,下面结合Lambda使用maxByOrNull

fun main() {    val list = listOf<String>("a", "aba", "aabb", "a")    var lambda = {str: String -> str.length}    var maxStr = list.maxByOrNull(lambda)    println(maxStr)}

直接当成参数也可传递

var maxStr = list.maxByOrNull({str: String -> str.length})

Lambda为方法的最后一个参数,则可将{}提到外面

var maxStr = list.maxByOrNull() {str: String -> str.length}

若有且仅有一个参数且是Lambda,则可去掉()

var maxStr = list.maxByOrNull {str: String -> str.length}

Kotlin拥有出色的类型推导机制,Lambda参数过多时可省略参数类型

var maxStr = list.maxByOrNull {str -> str.length}

Lambda只有一个参数,则可用it替代参数名

var maxStr = list.maxByOrNull {it.length}

集合还有许多此类函数

创建list,后续操作都由此list转换

val list = listOf<String>("a", "aba", "aabb", "a")

map 映射,返回新集合,将集合中的元素映射成另一个值

val newList = list.map { it.toUpperCase() }//将集合中的元素都准换成大写

filter过滤,返回新集合,将集合中的元素进行筛选

val newList = list.filter { it.length > 3 }//筛选出长度大于3的元素

any返回Boolean,集合中是否存在元素满足Lambda的条件,有则返回true,无则false

val isAny = list.any {it.length > 10} //返回false

all返回Boolean,集合中元素是否全部满足满足Lambda的条件,有则返回true,无则false

val isAll = list.all {it.length > 0} //返回true

Lambda的简单使用到这就结束了

Java函数式api的使用

Kotlin调用Java方法,若该方法接收一个Java单抽象方法接口参数,则可使用函数式APIJava单抽象方法接口指的是接口只声明一个方法,若有多个方法则无法使用函数式API

Java单抽象方法接口例如Runnable

public interface Runnable {    void run();}

Java中启动一个线程如下:

new Thread(new Runnable() {    @Override    public void run() {        System.out.println("test");    }}).start();

Kotlin启动线程如下:

Kotlin摒弃了new,若想声明匿名内部类必须使用object

Thread(object : Runnable {    override fun run() {        println("test")    }}).start()

RunnableJava单抽象方法接口,可对代码进行简化

Thread(Runnable {        println("test")    }).start()

Runnable接口只用一个方法,使用Lambda也不会有歧义,Kotlin知道此Lambda一定实现的为run函数,借用Lambda进一步简化:

Thread({    println("test")}).start()

又因Thread只需一个参数Runnable参数,则可省略()

Thread {    println("test")}.start()

与上类似的,click也使用上述方法

button.setOnClickListener { println("test") }

这种方式可极大缩减代码量

空指针检查机制

国外统计程序出现最多的异常为空指针异常,Kotlin存在编译时检查系统帮助我们发现空指针异常。

查看下面Java代码

public void doStudy(Study study) {    study.doHomework();    study.readBooks();}

上述代码时存在空指针风险的,传入null,则程序崩溃,对其进行改进

public void doStudy(Study study) {    if (study != null) {        study.doHomework();        study.readBooks();    }}

对于Kotlin来讲任何参数和变量不能为空

fun study(study: Study) {    study.doHomework()    study.readBooks()}fun main() {    study(null) //报错    study(Student()) //正确}

Kotlin把空指针异常的检查提前到了编译期,若空指针则编译期就会崩溃,避免在运行期出现问题

若我们有特殊的需求可能需要传递null参数,参数则按照下面声明

fun study(study: Study?) {    study.doHomework() //报错    study.readBooks()//报错}

?的意思则是当前参数可为空,如果可为空的话,则此对象调用的方法必须要保证对象不为空,上面代码没有保证,则报错,修改如下

fun study(study: Study?) {    if (study != null) {        study.doHomework()        study.readBooks()    }}

也可借助判空辅助工具

判空辅助工具

?.

其含义是前面对象不为空才执行.后面的方法

fun study(study: Study?) {    study?.doHomework()    study?.readBooks()}

?:

其含义是前不为空则返回问号前的值,为空则返回后的值

比如

val c = if (a !=null ) {    a} else {    b}

借助?:则可简化为

val c = a ?: b

再比如

fun getTextLength(text: String?): Int {    if (text != null) {        return text.length    }    return 0}

借助?: 则可简化为

fun getTextLength(text: String?) = text?.length ?: 0

!!

有些时候我们想要强行通过编译,就需要依靠!!,这时就是程序员来保证安全

fun study(study: Study?) {    //假设此时为空抛出异常,则和java一样    study!!.doHomework()    study!!.readBooks()}

let函数

let不是关键字,而是一个函数,提供了函数式API编程接口,会将调用者作为参数传递到Lambda表达式,调用之后会立马执行Lambda表达式的逻辑

obj.let { it -> //it就是obj    //编写操作}

比如上面函数

fun study(study: Study?) {    study.doHomework()  //报错    study.readBooks()//报错}

借助let则可改为

fun study(study: Study?) {    //此时靠?.则保证了study肯定不为空,才会执行let函数    study?.let {        //it为study        it.doHomework()        it.readBooks()    }}

全局判空注意事项

//全局变量var study: Study? = nullfun study() {    //报错    if (study != null) {        study.readBooks()        study.doHomework()    }}

因全局变量随时有可能被其他线程修改,即使判空处理也不能保证其没有空指针风险,而let则可规避上述问题

var study: Study? = nullfun study() {    study?.let {        it.doHomework()        it.readBooks()    }}

内嵌表达式

之前我们拼接字符串都是下面这样

var name = "zjm"var age = 20println("My name is " + name + ". I am " + age + ".")//打印结果//My name is zjm. I am 20.

现在靠着Kotlin提供的内嵌表达式则不需要拼接,只需要下面这样则可实现

var name = "zjm"var age = 20println("My name is $name. I am $age." )//打印结果//My name is zjm. I am 20.

内嵌表达式还支持复杂的操作

${程序员想要的操作}

var name = "zjm"var age = 20println("My name is ${if (1 < 2) "zjm" else "ljn"}. I am $age." )//打印结果//My name is zjm. I am 20.

函数的参数默认值

Kotlin支持函数存在默认值,使用如下

fun main() {    myPrint(1)    myPrint(1, "lalala")}fun myPrint(value: Int, str: String = "hello") {    println("num is $value, str is $str")}//结果如下//num is 1, str is hello//num is 1, str is lalala

value想为默认值,则会报错,因为在使用时传入的第一个参数他认为是int的,传入字符串会类型不匹配

fun main() {    myPrint("zjm")//报错}fun myPrint(value: Int = 100, str: String) {    println("num is $value, str is $str")}

Kotlin提供了一种键值对传参来解决上述问题

fun main() {    myPrint(str = "zjm") //正确调用}fun myPrint(value: Int = 100, str: String) {    println("num is $value, str is $str")}

回顾之前的主次构造,Student如下

class Student(name: String,  age: Int, val number: String, val grade: Int) : Person(name, age){    constructor(name: String, age: Int, number: String) : this(name, age, number, 0) {    }    ...}

上述的此构造借助参数默认值技巧是可以不写的,将第四个参数默认值为0 即可

class Student(name: String,  age: Int, val number: String, val grade: Int = 0) : Person(name, age){...}

上述关于Kotlin的使用,已经够日常开发需要,后续笔者会更新一些进阶使用

原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下}

👍 点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{green}{点赞,你的认可是我创作的动力!}

⭐️ 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{green}{收藏,你的青睐是我努力的方向!}

✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!}

来源地址:https://blog.csdn.net/zjm807778317/article/details/124188750

--结束END--

本文标题: Kotlin基础学习-入门篇

本文链接: https://lsjlt.com/news/397802.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Kotlin基础学习-入门篇
    本篇文章来自郭霖大佬的第一行代码中的Kotlin教程,笔者只是在学习Kotlin过程中记录学习过程。 Kotlin系列已更新: Kotlin基础学习-入门篇 Kotlin基础学习-第二篇 Kotli...
    99+
    2023-09-07
    kotlin android
  • Python基础学习入门
    Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。在命令行窗口输入"python" 命令来查看本地是否已经安装Python以及Python的安装版本Python下载Python官网:http://www...
    99+
    2023-06-02
  • linux 基础学习入门 3
    linux day 3第三天内容并不明确, 自我总结内部命令 用 help command   或  man bash外部命令 用 command --help 或  command -h使用手册 man command信息页 info c...
    99+
    2023-01-31
    入门 基础 linux
  • Tornado基础学习篇
    1.1 Tornado是什么? Tornado是使用Python编写的一个强大的、可扩展的Web服务器。它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中。 我们现在所知道的Tor...
    99+
    2023-01-30
    基础 Tornado
  • Android DataBinding 基础入门(学习记录)
    目录 一、DataBinding简介二、findViewById 和 DataBinding 原理及优缺点1. findViewById的优缺点2. DataBinding的优缺点 三、Android mvvm 之 data...
    99+
    2023-08-30
    android
  • Python学习入门基础教程(learn
     在Python里可以自定义函数,实现某特定功能,这里首先要区分一下函数的定义和函数的调用两个基本概念,初学者往往容易混淆。      函数的定义是指将一堆能实现特定功能的语句用一个函数名标识起来,而函数的调用则是通过函数名来使用这一堆语句...
    99+
    2023-01-31
    基础教程 入门 Python
  • Python学习入门基础教程(lear
      在if分支判断语句里的条件判断语句不一定就是一个表达式,可以是多个(布尔)表达式的组合关系运算,这里如何使用更多的关系表达式构建出一个比较复杂的条件判断呢?这里需要再了解一下逻辑运算的基础知识。逻辑关系运算有以下几种运算符.     ...
    99+
    2023-01-31
    基础教程 入门 Python
  • Python学习基础篇(一)
    Python简介和入门Python简介走进Pythonpython的创始人为吉多·范罗苏姆(Guido van Rossum)。1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一...
    99+
    2023-01-31
    基础 Python
  • Kotlin基础学习之位运算
    什么是位运算?程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进...
    99+
    2023-05-30
  • Kotlin基础入门 - for、forEach 循环
    不论身处何方 for循环这种操作都随处可见,鉴于大多数Android开发都是从Java转到Kt的,所以我的思路是从Java的使用习惯来讲一些Kt 的for、forEach 循环方式 基础 for循环惯性 for循环进阶 f...
    99+
    2023-08-19
    Android Kotlin for循环 forEach循环 step 多列表循环
  • 《零基础入门学习Python》【第一版】
    测试题答案: 0. 什么是BIF?BIF 就是 Built-in Functions,内置函数。为了方便程序员快速编写脚本程序(脚本就是要编程速度快快快!!!),Python 提供了非常丰富的内置函数,我们只需要直接调用即可,例如 pri...
    99+
    2023-01-31
    入门 基础 Python
  • C#多线程学习之基础入门
    目录同步方式异步多线程方式异步多线程优化异步回调异步信号量异步多线程返回值异步多线程返回值回调线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进...
    99+
    2024-04-02
  • Linux 学习基础入门之Linux分区
    安装Linux,首先要有镜像文件,以CentOS为例,可以在官网或者国内某些镜像Server来获取镜像。根据自己的需要可以选择是 Everything 或者minimal iso.这里不写关于安装的细节,对于其中的一些关键步骤做些说明。1....
    99+
    2023-06-05
  • 学习手册--Linux基础篇
    目录1. linux系统介绍1.1 linux的概述1.2 linux的优势1.3 linux的分类1.4 常见的发行版linux系统2. Linux的安装3. Linux的基础篇3.1 目录结构3.1.1 那具体有哪些...
    99+
    2022-06-04
    Linux学习 Linux基础
  • [Python]学习基础篇:字典
    字典字典这个数据结构的功能和它的名字一样,根据key得到value值。字典的定义 方法: dict={‘key1’:value1,’key2’:value2……..} 对于字典,key值在字典中不能重复,若出现重复,将更改原有的key对应的...
    99+
    2023-01-31
    字典 基础 Python
  • HBase入门修行基础篇
    HBase入门修行基础篇 HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigt...
    99+
    2024-04-02
  • SQL 教程-入门基础篇
    文章目录 SQL 简介SQL 语法SQL SELECT 语句SQL SELECT DISTINCT 语句SQL WHERE 子句SQL AND & OR 运算符SQL ORDER BY...
    99+
    2023-08-31
    sql 数据库 mybatis mysql
  • R语言学习-基础篇1
    ###第一周:R基础 rm(list = ls())  #ctr+L###矩阵相乘,函数diag()a=matrix(1:12,nrow=3,ncol=4)b=matrix(1:12,nrow=4,ncol=3)a%*%ba=matrix(...
    99+
    2019-01-18
    R语言学习-基础篇1
  • CTF之PHP基础学习篇(一)
    文章目录 前言CTF之PHP基础一、PHP是什么?二、配置PHP环境三、php基础语法 总结 前言 估摸着不少学计算机的同学以及其他专业的小部分同学都对于信息安全感兴趣吧!那对于参加...
    99+
    2023-10-02
    php 网络安全 学习
  • Nodejs学习笔记之入门篇
    分享第一篇,关于 NodeJS —— Javascript 的常用知识以及如何从 Javascript 开发者过渡到 NodeJS 开发者(不会介绍具体的框架)。在读本文前,希望你对 javascript ...
    99+
    2022-06-04
    学习笔记 入门篇 Nodejs
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作