全网最全面的由浅到深的Kotlin基础教程(一)

前言

kotlin是google全力推行的语言,如果你是从事android相关的研发,掌握kotlin语言是非常有必要的,因为现在google的很多新技术以及接口都是用kotlin语言实现的,如果你不懂kotlin语言,那么你就很难跟上google的最新技术。

其次,kotlin语言真的是集所有语言之大成,kotlin可以兼容目前主流的编程语言,而且kotlin代码精简之程度,真的是目前任何语言都无法比拟的,这一点,我也是认真学习完之后才体会到的,相信你看完本文,就能体会到kotlin语言的简洁程度。

总之,因为kotlin语言是集所有语言之大成,学习完kotlin也一定程度上可以让你加深对其它语言,尤其是java语言的进一步理解。我将通过7篇博文,完成kotlin入门系列教程,本篇是系列的开篇,下一篇是全网最全面的由浅到深的Kotlin基础教程(二)

那么,下面就开始我们的kotlin学习之旅吧,坚持看完本系列文章,你将掌握一门非常灵活的编程语言,相信一定会收获满满。

特别鸣谢Derry老师~~
如果想要看视频学习的,可以去B站看Derry老师的视频,Android Kotlin从入门到进阶全套教程

1. 声明变量及内置数据类型

  1. 声明变量格式:
    可读可写var/只读val 变量名 变量类型 值
  2. 声明变量示例
//声明可读可写的String类型变量name
var name:String ="sun"
//声明只读的String类型变量info
val info:String = "my info"
  1. kotlin内置变量类型
String 
Char
Boolean
Int
Float 
Double
List 集合
Set 无重复集合
Map 键值对
  1. kotlin输入函数println
var name:String ="sun"
name="hao"
println(name);

2. 类型推断

kotlin具有类型推断的能力,如果类型没有歧义,可以省略指定类型,由编译器自动推断类型。

//val age:Int = 18
val age = 18  //如编译器可以推断出age的类型为Int,因此类型Int可以省略

3. 定义编译时常量

通过const修饰val变量,定义编译时常量

const val PI =3.1415926

4. 查看反编译后的字节码/java代码

kotlin可以兼容Java代码,IDEA工具通过Tools -->Kotlin --> Show Kotlin Bytecode --> Decompile可以查看kotlin反编译为java的代码。通过反编译工具,可以深入理解kotlin的实现逻辑。

如下kotlin代码

package com.kt.base

// TODO 编译时常量
const val PI =3.1415926
fun main() {
    println(PI)
}

通过IDEA查看反编译为java代码如下,从反编译的java代码可见,kotlin所谓的const val变量转为java代码,其实就是static final变量。

package com.kt.base;

import kotlin.Metadata;

@Metadata(
   mv = {1, 7, 0},
   k = 2,
   d1 = {"\u0000\u000e\n\u0000\n\u0002\u0010\u0006\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 = {"PI", "", "main", "", "KotlinLearn"}
)
public final class Kt04Kt {
   public static final double PI = 3.1415926;

   public static final void main() {
      double var0 = 3.1415926;
      System.out.println(var0);
   }

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

5. range表达式

用于范围判断

fun main() {
    val score = 99
    if (score in 60..100) {
        println("及格")
    } else {
        println("不及格")
    }
}

6. when表达式

类似java的switch case

fun main() {
    var week = 6
    var info = when(week){
        1 -> "星期一"
        2 -> "星期二"
        3 -> "星期三"
        4 -> "星期四"
        5 -> "星期五"
        else -> {
            println("星期不知道") //Unit就是java中的void返回类型
        }
    }
    println(info)
}

7. String模板

kotlin String可以通过$符号进行变量引用和逻辑编写等。

fun main() {
    var address = "北京"
    var feel = "很好"
    println("今天我去${address}玩了,我感觉${feel}")

    //kotlin的if是表达式,更灵活,java的if是语句
    var isLogin = true
    println("当前登录状态 ${if (isLogin) "登录成功" else "登录失败"}")
}

8. 函数学习

8.1 函数头学习

函数格式
修饰符 fun 方法名(参数名:类型):返回类型{}

//不写修饰符,默认为public
private fun method1(age:Int, name:String):Int{
    println("你的名字是$name,你的年龄是$age")
    return 200
}

8.2 函数参数的默认参数

fun main() {
    method1() //省略参数,则采用默认的参数 
}
private fun method1(name:String="sun", age:Int=18){
    println("你的名字是$name,你的年龄是$age")
}

8.3 具名函数参数

不依靠函数参数的顺序确定参数值,而是直接指定参数名确定参数值。

fun main() {
    method1(age=18, name="sun")
}

private fun method1(name:String, age:Int){
    println("你的名字是$name,你的年龄是$age")
}

8.4 Unit函数的特点

Unit函数即java中返回值void的函数

// Unit返回类型可以省略不写
private fun method1():Unit
{

}

8.5 Nothing类型的特点

kotlin中Nothing类型的函数就是java中抛异常的函数,用于抛出异常。
官方对于Nothing类的定义及介绍如下,简言之,就是通过抛异常,处理不存在值的情况。

/**
 * Nothing has no instances. You can use Nothing to represent "a value that never exists": for example,
 * if a function has the return type of Nothing, it means that it never returns (always throws an exception).
 */
public class Nothing private constructor()

如kotlin中TODO函数的返回类型就是Nothing,用于抛出异常。

public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")

TODO函数使用示例

private fun method1(score:Int){
    when(score){
        -1 -> TODO("没有这种情况")
        in 0..60 -> "不及格"
        in 61..70 -> "及格"
        in 71..100 -> "优秀"
    }
}

8.6 反引号(`)中函数名特点:

kotlin可以通过反引号,定义一些违反命名规则的方法

fun main() {
    `我的函数`("sun", 18)
}

private fun `我的函数`(name:String, age:Int){
    println("name:${name},age:$age")
}

8.7 定义函数类型 & 隐式返回

  • 定义函数类型:可以像定义基础变量一样定义函数类型
  • 隐式返回:把函数体中的最后一行作为返回值

代码示例如下:

fun main() {
    //1. 函数声明 方法名:输入->输出
    val method1:()->String
    //2. 函数实现
    method1 = {
        //匿名函数不用写return,最后一行就是返回值
        "success"
    }
    //3. 函数调用
    println(method1())
}

8.8 匿名函数的学习

上面8.7节定义的函数类型,推荐通过下面的方式直接进行匿名实现,而不必,先定义函数,再去实现函数。下面的示例就是匿名函数写法。

fun main() {
    //1. 函数声明 方法名:输入->输出,及函数实现【这种匿名写法与下面的函数效果一致】
    val method1:(String,Int)->String = {name, age ->
        "name:$name,age:$age"
    }
    //3. 函数调用
    println(method1("sun", 18))
}

private fun method1(name:String,age:Int):String{
    return "name:$name,age:$age"
}

8.9 it关键字特点

匿名函数如果只有一个参数,默认参数名为it,当然你也可以指明参数名。

fun main() {
    val method1:(Int)->String = {
        "it=$it"
    }
    println(method1(66))
}

8.10 匿名函数的类型推断

匿名函数有两种写法:

  • 可以进行类型推断的写法:
    方法名 = {入参类型 -> code body}
  • 不可以进行类型推断的写法:
    方法名 : (入参类型) -> 返回类型 = {入参名 -> code body}

关于类型推断很简单,只要没有歧义,确定是某一种类型,编译器都可以进行类型推断。

fun main() {
    //匿名函数写法一(可以进行类型推断,不需要写返回类型) 方法名 = {入参 -> code body}
    val method = {v1:Int, v2:String ->
            "v1:$v1,v2:$v2"
    }
    println(method(18, "sun"))
   //匿名函数写法二(无法进行类型推断):方法名 : (入参类型) -> 返回类型 = {入参名 -> code body}
    val method1 : (Int, String) -> String = {v1, v2 ->
        "v1:$v1,v2:$v2"
    }
    println(method1(18, "hao"))
}

8.11 lambda表达式学习

匿名函数属于lambda表达式,即上面学习的匿名函数就是lambda表达式。

fun main() {
    //add 匿名函数也就是lambda表达式
    val add = {num1:Int, num2:Int ->
        "add = ${num1+num2}"
    }
    println(add(1,5))
    //week 匿名函数也就是lambda表达式
    val week = {num:Int ->
        when(num){
            1 -> "星期1"
            2 -> "星期2"
            3 -> "星期3"
            4 -> "星期4"
            5 -> "星期5"
            else -> -1
        }
    }// week : (Int) -> Any
    println(week(1))
}

8.12 函数中定义参数为函数

即函数参数为lambda表达式,如果用java,就需要用接口实现。

fun main() {
    loginAPI("mekeater", "123") { msg:String, code:Int ->
        println("登录结果 msg:$msg,code:$code")
    }
}

//将函数通过lambda表达入参,如果用java,就需要用接口实现
fun loginAPI(name:String, pwd:String, responseResult: (String, Int) -> Unit)
{
    if (name == "mekeater" && pwd == "123")
    {
        responseResult("登录成功", 200)
    }
    else{
        responseResult("登录失败", 444)
    }
}

8.13 函数内联学习

  • 通过inline修饰符可以将函数指定为内联函数。
  • 建议函数参数中有lambda表达式的函数,都声明为内联函数,否则,调用端会生成多个对象才能完成lambda的调用,影响程序性能。你可以通过反编译为java代码查看这一事实。
fun main() {
    loginAPI1("mekeater", "123") { msg:String, code:Int ->
        println("登录结果 msg:$msg,code:$code")
    }
}

//将函数通过lambda表达入参,如果用java,就需要用接口实现
inline fun loginAPI1(name:String, pwd:String, responseResult: (String, Int) -> Unit)
{
    if (name == "mekeater" && pwd == "123")
    {
        responseResult("登录成功", 200)
    }
    else{
        responseResult("登录失败", 444)
    }
}

8.14 函数引用学习

lambda表达式参数如果采用具体函数实现,则需要通过函数引用(::)进行调用。示例代码如下:

fun main() {
    //lambda属于函数类型的对象,需要把responseMethod方法转变为 函数类型的对象(函数引用::)
    val obj = ::responseMethod
    login("mekeater", "123", obj)
}

//lambda表达式具名函数实现
private fun responseMethod(msg:String, code:Int){
    println("登录情况 msg:$msg, code:$code")
}

inline fun login(name:String,psw:String, responseResult:(String, Int)->Unit){
    if (name == "mekeater" && psw == "123")
    {
        responseResult("登录成功", 200)
    }
    else{
        responseResult("登录失败", 444)
    }
}

8.15 函数类型作为返回类型

即以lambda表达式作为函数的返回类型。

fun main() {
    var show = show("返回匿名函数")
    println(show("sun", 18))
}

fun show(info: String): (String, Int) -> String {
    println("info$info")
    return { name: String, age: Int ->
        "name:$name, age:$age"
    }
}

8.16 匿名函数与具名函数

上面也提到了,lambda表达式匿名实现的称为匿名函数,lambda表达式单独用一个函数实现的,称为具名函数。示例如下:

fun main() {
    //lambda表达匿名实现,匿名函数
    show("sun", "he is a success man") {
        println("result = $it")
    }

    //showResultImpl是具名函数
    show("sun", "he is a success man", ::showResultImpl)
}

//具名函数
fun showResultImpl(result:String){
    println("result = $result")
}

inline fun show(name:String, info:String, showResult:(String)->Unit){
    val str = "name:$name,info:$info"
    showResult(str)
}
  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于全网最详细的VSCode教程,以下是一个简短的描述: 全网最详细的VSCode教程应该包含以下内容:基本介绍、安装和设置、编辑器布局、常用快捷键、实用插件和扩展、调试功能、版本控制、代码片段等。 在基本介绍部分,应该详细介绍VSCode是什么,它的优点和特点,如何下载和安装等。 安装和设置部分应该涵盖不同操作系统上的安装步骤和注意事项。同时,还应该介绍不同配置选项,如主题、字体、缩进设置等。 编辑器布局部分应该解释各个面板和视图的作用,如侧边栏、编辑窗口、终端等。详细说明如何调整布局以优化工作流程。 常用快捷键部分应该列举常用的快捷键和相关操作,如快速打开文件、搜索、查看定义等。应该对不同功能区分操作系统进行说明。 实用插件和扩展部分应该介绍一些常见和有用的插件,如代码片段、代码格式化、调试器等。应该详细解释如何安装和使用这些插件。 调试功能部分应该详细介绍如何配置和使用调试器,包括设置断点、查看变量的值等。 版本控制部分应该介绍如何使用内置的版本控制工具,如Git,如何提交、推送和拉取代码等。 最后,代码片段部分应该教授如何创建和使用代码片段,以提高编码效率。 以上仅是对全网最详细的VSCode教程的一些简要描述。当然,真正最详细的教程可能比这个更加全面和详细,具体内容可能还包括更多高级功能和技巧。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mekeater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值