Kotlin小菜——基础语言教程

news2024/11/23 3:50:51

概述

Kotlin是JetBrains推出的一种编程语言,JetBrains是最智能的Java IDE的官方设计器,名为Intellij IDEA。这是在JVM上运行的强静态类型语言。2017年,谷歌宣布Kotlin是Android开发的官方语言。Kotlin是一种开源编程语言,它将面向对象的编程和功能特性组合到一个独特的平台中。内容分为不同的章节,其中包含相关主题以及简单而有用的示例。

Kotlin受其他编程语言(例如Java,Scala,Groovy,Gosu等)的影响。Kotlin的语法可能与JAVA并不完全相似,但是Kotlin在内部依靠现有的Java类库为程序员提供了出色的结果。Kotlin为全球开发人员提供了互操作性,代码安全性和清晰度。

Kotlin特点

  • 简洁 Kotlin比Java更简洁,与Java相比,您需要少写大约40%的代码行。
  • 互操作性 Kotlin与Java具有高度互操作性。在Java项目中使用Kotlin不会遇到任何困难。
  • 开源 Kotlin是一种开源编程语言。

基本语法

2.1、类、方法、变量

1、行末分号可以省略, 2、变量、参数、方法返回的类型写在冒号后面, 3、创建对象不用new, 4、注释和java一样, 5、$p拼接字符串。

package hello                                  //  可选的包头
​
fun main(args: Array<String>) {                // 包级可见的函数,args 参数,Array<String> 参数类型
   println("Hello World!")
   val s = "字符串"
   val str = "$s.length is ${s.length}" // 求值结果为 "runoob.length is 6"
   println(str)
​
    val price = "${'$'}9.99"
    println(price)  // 结果为 $9.99
}
​
fun sum(a: Int, b: Int): Int {                  // Int 参数,返回值 Int
    return a + b
}
​
public fun sum(a: Int, b: Int): Int = a + b     // public 方法则必须明确写出返回类型
​
class Greeter(val name: String) {
   fun greet() { 
      println("Hello, $name")                   // 用$拼接字符串
   }
}
​
fun gg(): Unit {                               // Unit 无返回值,相当于void,也可以省略
    Greeter("World!").greet()                  // 创建一个对象不用 new 关键字
}
​

2.2、var 、val 、vararg

var 可修改变量、val 不可修改变量
​
val a: Int = 1
val b = 1       // 系统自动推断变量类型为Int
val c: Int      // 如果不在声明时初始化则必须提供变量类型
c = 1           // 明确赋值
​
​
var x = 5        // 系统自动推断变量类型为Int
x += 1           // 变量可修改

vararg 可变产长参数

fun vars(vararg v:Int){
    for(vt in v){
        print(vt)
    }
}
​
fun main(args: Array<String>) {
    vars(1,2,3,4,5)  // 输出12345
}

2.3、匿名函数

fun main(args: Array<String>) {
    val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
    println(sumLambda(1,2))  // 输出 3
}

2.4、NULL检查机制

//类型后面加?表示可为空
var age: String? = "23" 
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1

当一个引用可能为 null 值时, 对应的类型声明必须明确地标记为可为 null。 当 str 中的字符串内容不是一个整数时, 返回 null

fun parseInt(str: String): Int? {
    return str.toIntOrNull()
}

2.5、类型判断

fun getStringLength(obj: Any): Int? {
  if (obj is String) {                                          // 单行if,{}可以省略
    // 做过类型判断以后,obj会被系统自动转换为String类型
    return obj.length 
  }
​
  //在这里还有一种方法,与Java中instanceof不同,使用!is
  // if (obj !is String){
  //   // XXX
  // }
​
  // 这里的obj仍然是Any类型的引用
  return null
}

2.6、数据类型

Kotlin 的基本数值类型包括 Byte、Short、Int、Long、Float、Double 等。不同于 Java 的是,字符不属于数值类型,是一个独立的数据类型。

字面量: 1、长整型以大写的 L 结尾:123L 2、16 进制以 0x 开头:0x0F 3、2 进制以 0b 开头:0b00001011 4、注意:8进制不支持 5、Doubles 默认写法: 123.5, 123.5e10 6、Floats 使用 f 或者 F 后缀:123.5f 7、数字中可以使用下划线,使数字更易读

val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

在 Kotlin 中,三个等号, 表示比较对象地址,两个等号表示比较两个值大小。 Byte、Short、Int等这些基本类型也有对象地址。

println(a === a) // true,值相等,对象地址相等

toByte()、toShort()、toInt()、toLong()等方法用于类型间转换。

val b: Byte = 1
val i: Int = b.toInt()

Char 不能直接和数字操作,Char 必需是单引号 ’ 包含起来

fun check(c: Char) {
    println(c == 1)                 // false
    println(c == '1')               // true
}

多行字符串可以用三个引号

fun main(args: Array<String>) {
    val text = """
    |第一行
    |第二行
    |第三行
    |第四行
    """.trimMargin()         //  trimMargin() 方法删除多余的空白
    println(text)
}

2.7、异常

fun decimalDigitValue(c: Char): Int {
    if (c !in '0'..'9')
        throw IllegalArgumentException("Out of range")
    return c.toInt() - '0'.toInt()
}

2.8、数组

fun main(args: Array<String>) {
    //[1,2,3]
    val a = arrayOf(1, 2, 3)
    //[0,2,4]
    val b = Array(3, { i -> (i * 2) })
​
    //读取数组内容
    println(a[0])    // 输出结果:1
    println(b[1])    // 输出结果:2
}

2.9、条件控制

var max: Int
if (a > b) {
    max = a
} else {
    max = b
}
​
// 作为表达式
val max = if (a > b) a else b
​
val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}

when类似 switch

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> { // 注意这个块
        print("x 不是 1 ,也不是 2")
    }
}
​
​
when (x) {
    0, 1 -> print("x == 0 or x == 1")
    else -> print("otherwise")
}
​
​
when (x) {
    in 1..10 -> print("x is in the range")
    in validNumbers -> print("x is valid")
    !in 10..20 -> print("x is outside the range")
    else -> print("none of the above")
}
​
fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")
    else -> false
}
​
​
when {
    x.isOdd() -> print("x is odd")
    x.isEven() -> print("x is even")
    else -> print("x is funny")
}

for循环

// 迭代器
for (item in collection) print(item)
​
for (item: Int in ints) {
    // ……
}
​
// list
for (i in array.indices) {
    print(array[i])
}
​
fun main(args: Array<String>) {
    val items = listOf("apple", "banana", "kiwi")
    for (item in items) {
        println(item)
    }
​
    for (index in items.indices) {
        println("item at $index is ${items[index]}")
    }
}

在循环中 Kotlin 支持传统的 break 和 continue 操作符。 return 允许我们从外层函数返回, 从 lambda 表达式中返回,我们必须给它加标签并用以限制 return。

// return结束整个foo
fun foo() {
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}
​
// return结束forEach
fun foo() {
    ints.forEach lit@ {
        if (it == 0) return@lit
        print(it)
    }
}
​
// 函数名也是一个标签
fun foo() {
    ints.forEach {
        if (it == 0) return@forEach
        print(it)
    }
}

当要返一个回值的时候,解析器优先选用标签限制的 return

return@a 1

2.10、类

class Baidu {
    var name: String = "百度"
    var url: String = "www.baidu.com"
    var city: String = "北京"
}
​
val site = Runoob()
println(site.name)
​
// constructor主构造器,这个关键字可以省略
class Person constructor(firstName: String) {}

getter 和 setter 都是可选

var allByDefault: Int? // 错误: 需要一个初始化语句, 默认实现了 getter 和 setter 方法
var initialized = 1    // 类型为 Int, 默认实现了 getter 和 setter
val simple: Int?       // 类型为 Int ,默认实现 getter ,但必须在构造函数中初始化
val inferredType = 1   // 类型为 Int 类型,默认实现 getter

实例

class Person {
​
    var lastName: String = "zhang"
        get() = field.toUpperCase()   // 将变量赋值后转换为大写
        set
    
    var no: Int = 100
        get() = field                // 后端变量
        set(value) {
            if (value < 10) {       // 如果传入的值小于 10 返回该值
                field = value
            } else {
                field = -1         // 如果传入的值大于等于 10 返回 -1
            }
        }
    
    var heiht: Float = 145.4f
        private set
}
​
// 测试
fun main(args: Array<String>) {
    var person: Person = Person()
​
    person.lastName = "wang"
    
    println("lastName:${person.lastName}")
    
    person.no = 9
    println("no:${person.no}")
    
    person.no = 20
    println("no:${person.no}")
​
}

field 后端变量 field 关键词只能用于属性的访问器

var no: Int = 100
        get() = field                // 后端变量
        set(value) {
            if (value < 10) {       // 如果传入的值小于 10 返回该值
                field = value
            } else {
                field = -1         // 如果传入的值大于等于 10 返回 -1
            }
        }

init 关键字初始化代码段

class Person constructor(firstName: String) {
    init {
        println("FirstName is $firstName")
    }
}

二级构造函数

class Person { 
    constructor(parent: Person) {
        parent.children.add(this) 
    }
}
​
// this调用主构造函数的name
class Person(val name: String) {
    constructor (name: String, age:Int) : this(name) {
        // 初始化...
    }
}

abstract抽象类

如果一个类要被继承,可以使用 open 关键字进行修饰。

open class Base {
    open fun f() {}
}
​
abstract class Derived : Base() {
    override abstract fun f()
}

内部类使用 inner 关键字来表示。 内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数。

class Outer {
    private val bar: Int = 1
    var v = "成员属性"
    /**嵌套内部类**/
    inner class Inner {
        fun foo() = bar  // 访问外部类成员
        fun innerTest() {
            var o = this@Outer //获取外部类的成员变量
            println("内部类可以引用外部类的成员,例如:" + o.v)
        }
    }
}
​
fun main(args: Array<String>) {
    val demo = Outer().Inner().foo()
    println(demo) //   1
    val demo2 = Outer().Inner().innerTest()   
    println(demo2)   // 内部类可以引用外部类的成员,例如:成员属性
}

interface 与 匿名内部类

class Test {
    var v = "成员属性"
​
    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}
​
/**
 * 定义接口
 */
interface TestInterFace {
    fun test()
}
​
fun main(args: Array<String>) {
    var test = Test()
​
    /**
     * 采用对象表达式来创建接口对象,即匿名内部类的实例。
     */
    test.setInterFace(object : TestInterFace {
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })
}

类的修饰符

abstract    // 抽象类  
final       // 类不可继承,默认属性
enum        // 枚举类
open        // 类可继承,类默认是final的
annotation  // 注解类
​
private    // 仅在同一个文件中可见
protected  // 同一个文件中或子类可见
public     // 所有调用的地方都可见
internal   // 同一个模块中可见

属性重写使用 override 关键字

open class Foo {
    open val x: Int get { …… }
}
​
class Bar1 : Foo() {
    override val x: Int = ……
}

扩展函数

class User(var name:String)
​
/**扩展函数**/
fun User.Print(){
    print("用户名 $name")
}
​
fun main(arg:Array<String>){
    var user = User("Runoob")
    user.Print()
}

伴生对象的扩展

class MyClass {
    companion object { }  // 将被称为 "Companion"
}
​
fun MyClass.Companion.foo() {
    println("伴随对象的扩展函数")
}
​
val MyClass.Companion.no: Int
    get() = 10
​
fun main(args: Array<String>) {
    println("no:${MyClass.no}")
    MyClass.foo()
}

数据类,声明一个密封类,使用 data 修饰类

data class User(val name: String, val age: Int)
​
fun main(args: Array<String>) {
    val jack = User(name = "Jack", age = 1)
    // 复制数据
    val olderJack = jack.copy(age = 2)
    println(jack)
    println(olderJack)
​
}

密封类,声明一个密封类,使用 sealed 修饰类

sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
​
fun eval(expr: Expr): Double = when (expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
}

泛型

class Box<T>(t: T) {
    var value = t
}
val box: Box<Int> = Box<Int>(1)
// 或者
val box = Box(1) // 编译器会进行类型推断,1 类型 Int,所以编译器知道我们说的是 Box<Int>。
​
​
fun <T> boxIn(value: T) = Box(value)
​
// 以下都是合法语句
val box4 = boxIn<Int>(1)
val box5 = boxIn(1)     // 编译器会进行类型推断
​
// Comparable上约束
fun <T : Comparable<T>> sort(list: List<T>) {
    // ……
}
​
​
​
// 使用 out 使得一个类型参数协变
// 定义一个支持协变的类
class Runoob<out A>(val a: A) {
    fun foo(): A {
        return a
    }
}
​
fun main(args: Array<String>) {
    var strCo: Runoob<String> = Runoob("a")
    var anyCo: Runoob<Any> = Runoob<Any>("b")
    anyCo = strCo
    println(anyCo.foo())   // 输出 a
}

对象表达式

// 通过对象表达式实现一个匿名内部类的对象用于方法的参数中
window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }
    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})
​
// 对象可以继承于某个基类,或者实现其他接口
open class A(x: Int) {
    public open val y: Int = x
}
​
interface B {……}
​
val ab: A = object : A(1), B {
    override val y = 15
}

以上是Kotlin的基础语言的学习,更多进阶Kotlin的学习可以前往《Kotlin精通学习》里面从0到1的系统学习。推荐大家参考学习。

我的第一个Kotlin程序

为了激起您的学习程序,来尝试一下第一个Kotlin程序吧

fun main(args: Array<string>) {
    println("Hello, World!")
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

会话Cookie跟踪技术

会话 用户打开浏览器&#xff0c;访问web服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断开连接&#xff0c;会话结束。在一次会话中可以包含多次请求和响应。 从浏览器发出请求到服务端响应数据给前端之后&#xff0c;一次会话(在浏览器和服务器之间)就被建立了 …

产品设计:Material Design 学习笔记二

​5、图标 桌面图标 桌面图标尺寸是48dp X 48dp。 桌面图标建议模仿现实中的折纸效果&#xff0c;通过扁平色彩表现空间和光影。注意避免以下问题&#xff1a; ①不要给彩色元素加投影 ②层叠不要超过两层 ③折角不要放在左上角 ④带投影的元素要完整展现&#xff0c;不能…

Debug怎么用

文章目录前言一、打断点运行Debug二、页面重新运行功能三、回到代码看断点前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 因为最近有个项目注册不好使&#xff0c;想看看哪的问题&#xff0c;所以用debug看看程序走到了哪 提示&#xff1a;以下是本篇文…

docker部署mysql初始化数据库

一、前言 在使用docker部署mysql服务时&#xff0c;往往需要在创建容器时新建database&#xff0c;在需要在创建实例的过程中希望初始化sql脚本。 mysql官方镜像支持在容器初次启动时自动执行指定的sql脚本或shell脚本&#xff08;注意&#xff1a;只有初次启动时才能自动执行&…

【正点原子I.MX6U-MINI】通过tftp从Ubuntu中下载zImage 和设备树文件 | 从网络启动Linux系统

从网络启动linux系统的唯一目的就是为了调试&#xff01;不管是为了调试linux系统还是linux下的驱动。每次修改linux系统文件或者linux下的某个驱动以后都要将其烧写到EMMC中去测试&#xff0c;这样太麻烦了。我们可以设置linux从网络启动&#xff0c;也就是将 linux 镜像文件和…

【OpenCV-Python】教程:5-3 光流

OpenCV Python Optical Flow (光流) 【目标】 了解光流的概念和用 Lucas-Kanade 算法估计光流我们将使用cv2.calcOpticalFlowPyrLK()这样的函数来跟踪视频中的特征点。们将使用cv2.calcOpticalFlowFarneback()方法创建一个密集的光流场&#xff0c;可以用于前景检测。 【理论…

[附源码]Python计算机毕业设计高校心理咨询管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

Java+SSH实验室预约系统(含源码+论文+答辩PPT等)

该项目采用技术&#xff1a; 后台&#xff1a;SpringSpringmvcHibernate 前台JqueryMy97DatePickercssjs 使用了MySQLTomcat等相关技术 项目含有源码、文档、配套开发软件、软件安装教程、项目发布教程等 本系统的用户可以分为三种&#xff1a;管理员、教师、学生。以下针对三种…

协同共进 | 中睿天下入会工业信息安全产业发展联盟

近日&#xff0c;中睿天下加入“工业信息安全产业发展联盟”&#xff0c;成为新一批会员单位。 工业信息安全是网络安全、国家安全的重要组成部分&#xff0c;涉及工业领域各个环节,涵盖工业控制系统安全、工业互联网安全、工业数据安全等各领域&#xff0c;直接关系到经济发展…

u盘出现fat32如何恢复文件?告诉你两种好方法

u盘由于体积小、内存大等优势&#xff0c;在日常生活领域应用的很多&#xff0c;但是使用过程中&#xff0c;总会遇到这样或那样的问题&#xff0c;比如u盘显示fat32打开啥都没有了&#xff1f;或者u盘出现fat32而无法访问的情况&#xff0c;这时如果里面有重要的数据怎么办呢&…

Activiti 工作流引擎

一、什么是工作流&#xff1f; 工作流:指业务过程的部分或整体在计算机应用环境下的自动化。是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。在计算机中&#xff0c;工作流属于计算机支持的协同工作&#xff08;CSCW&#xff09;的一部分&#xff0c;后者是普遍研究…

win7无损合并分区,win7合并磁盘分区

电脑的操作系统是win7的&#xff0c;如果磁盘分区太小或者说磁盘分区不合理&#xff0c;需要对磁盘分区重新分区&#xff0c;其中合并磁盘分区就是解决方法之一&#xff0c;那么&#xff0c;有没有关于win7无损合并分区的操作方法呢&#xff1f; 一、利用Windows自带的功能来合…

Matlab|基于BP神经网络进行电力系统短期负荷预测

目录 摘要 一、电力负荷数据导入 二、输入输出数据归一化 三、建立和训练BP神经网络 四、 使用测试数据进行负荷预测 五、Matlab代码实现 摘要 使用BP神经网络实现简单的电力负荷回归预测任务。主要的步骤为&#xff1a;导入数据、数据归一化、建立BP神经网络、训练BP神…

熹乐科技范维肖CC:基于开源 YoMo 框架构建“全球同服”的 Realtime Metaverse Application

前言 在「RTE2022 实时互联网大会」中&#xff0c;熹乐科技创始人 & CEO 范维肖CC 以《基于开源 YoMo 框架构建“全球同服”的 Realtime Metaverse Application》为题进行了主题演讲。 本文内容基于演讲内容进行整理&#xff0c;为方便阅读略有删改。 大家好&#xff0c;…

chatGPT的爆火,是计算机行业这次真的“饱和”了?

近日&#xff0c;chatGPT这一生成式AI爆火&#xff0c;这款号称神仙级别的自动语言生成式AI发布短短5天内&#xff0c;就吸引了100万用户&#xff0c;在官方描述中&#xff0c;chatGPT是一个“可以连续回答问题、承认自己的错误、挑战不正确的前提并拒绝不适当的要求”的对话模…

【GO】 K8s 管理系统项目[API部分--Deployment]

K8s 管理系统项目[API部分–Deployment] 1. 实现接口 service/dataselector.go package serviceimport ("sort""strings""time"appsv1 "k8s.io/api/apps/v1"corev1 "k8s.io/api/core/v1" )// dataselector 用于排序,过滤…

第11讲:vue脚手架集成ElementUI

一、创建vue路由项目并添加ElementUI支持 ElementUI官方网站&#xff1a;ElementUI组件 创建路由项目请参考&#xff1a;路由开发 使用如下命令集成ElementUI npm i element-ui -S在src/main.js文件中引用ElementUI import Vue from vue import App from ./App.vue import …

创建第一个QT程序demo

双击Qt Creator 9.0.0 (Community)图标&#xff0c;打开软件。该图标所处位置为&#xff08;如果是默认安装到C盘下面的话&#xff09;&#xff1a;C:\Qt\Tools\QtCreator\bin\qtcreator.exe 或者从开始菜单栏启动&#xff08;开始菜单栏的启动图标本质上也是一个快捷方式&…

记录windows上的VSCODE 远程到linux编译代码机器上的一些问题

设置windows SSH 到linux时免密码登录的方法&#xff1a; 将C:\Users\Administrator.ssh\id_rsa.pub中的公钥字符串复制&#xff0c;追加到linux ~/.ssh/authorized_keys文件中。 问题&#xff1a; rootlocalhost:~/.vscode-server/bin/6261075646f055b99068d3688932416f2346d…

[附源码]Node.js计算机毕业设计服装创意定制管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…