1Kotlin基础知识
1 变量
1.1 用法
Kotlin中的变量定义有2个关键字,val和var
val用来定义不可变变量,第一次赋值后就不能再被修改了, var定义可变变量, 随便修改。一个好的编程习惯是, 能用val的就不要用var, 原因是安全, 这也是Kotlin中强制让你指明变量是否可变的原因。
针对变量定义, Kotlin有一个非常重要的机制, 类型自动推导, 那意味着可以告别C/C++, Java, 等语言中非常繁琐的变量定义方法。
1.2 对比示例
上几个例子感受一下这种变量定义的简洁之处吧。
Kotlin定义方式:
val name = 'leo'
var age = 18
python定义方式:
name = 'leo'
age = 18
java定义方式:
string name = 'leo';
int age = 18;
简洁性方面, 高下立判。 python yyds! Kotlin也还不错。 但这里不是为了比较不同编程语言, 仅仅是为 了对比加深印象。
上面的例子中, Kotlin就省略了类型定义, 其实是有编译器自动帮我们推导的。类型自动推导可以满足大多数的要求, 但有些场景类型是无法自动推导出来的,比如延迟赋值等场景, 这个时候还是需要手动指明变量类型的。如果需要手动指明的话, 方法是在变量名后加: 变量类型, 如:
val name : String = 'leo'
var age : Int = 18
写法上还是比较自然的。
2 函数
编程中经常会有函数和方法两个术语, 其实两者完全一样, 没有任何区别, 习惯叫法不同而已。
函数就是一堆代码的集合,为了方便, 把多条代码封装在一起。
2.1 函数写法
直接上个例子,对例子讲解吧:
fun myFunc(name: String, age: Int) : Int{return 0
}
要点如下:
- 1 函数定义用关键字
fun(function的缩写) - 2
myFunc是函数名, 建议起名遵循命名规范以及见名知意的原则 - 3 小括号中是函数可以接受的入参,按照
变量名:变量类型的格式书写, 没有入参可以空着不写 - 4 小括号外的
:Int定义了返回值类型, 同样的, 没有返回值也可以省略 - 5 {}中的是函数体, 也就是具体实现的代码, 只有一行的话可以省略大括号。
2.2 对比示例
python写法:
def myFunc(name, age):return 0
java写法:
public static int myFunc(string name, int age){return 0;
}
3 条件语句
3.1 常规的if else
fun getScore(score: Int){if (score>80){print("Very good")}else if (score>60) {print("Good")}else {print("Bad")}
}
上面是常规的 if else 语句,比较简单直观,应该不会过多讲解。
3.2 简洁而强大的when
when语句相当于其他编程语言中的swith case 语句, 但是更加简洁和强大。
fun getScore(score: Int){when(score) {80-> print("Very Good")60-> print("Good")else -> print("Bad")}
}
语法要点是, 在when中传入一个任意类型的参数, when的结构体中定义一系列的条件, 格式是:
匹配值 -> {执行逻辑}。 当执行逻辑只有一句时, 可以省略{}。 也就得到了上面代码的写法。
注意上面用when语句写的代码功能与上面用if else写的不一样。因为when接收的是一个参数, 而上面if else 中的条件是一个表达式。 那这时候就可以用无参数的when表达式了。
fun getScore(score: Int){when {score>80 -> print("Very Good")score>60 -> print("Good")else -> print("Bad")}
}
注意代码的变化, 因为无参数传入,when后面的括号不需要了, 表达式的计算放在when的结构体里面。 这个代码的功能就跟上面的if else定义的完全一致了。
4 循环语句
4.1 while循环
var index =5
while (index>0) {println(index)index --
}
输出 5 4 3 2 1
var index =5
do {prinltn(index)index --}
while (index>0)
}
输出 5 4 3 2 1
4.2 for循环
Kotlin的for in 循环与python非常类似, 基本语法是for (变量 in 可迭代对象), 可迭代对象包括数组, 列表等等。
for (index in 1..10)println(index)
上面的1…10是一个区间, 它是一个可迭代的对象。 ..是创建两端闭区间的关键字。 也就是说, 上面的区间是包含1和10的。 通常我们用的左闭右开区间多一些, 这个时候用until, 1 until 10, 就是1到9,不包括10。 还能通过step控制步长, downTo可以实现降序, 10 downTo 1 就是从10 到1.
for (index in 1..10 step 2)println(index)
5 类
类是面向对象编程中最重要的概念了。
5.1 类的定义
先上个示例:
class Person() {val name = "leo"val age = 18fun getInfo() {print("name is: $name , age is: $age.")}
}
fun main() {val person = Person()person.getInfo()
}
类的定义用关键字class, Person是类名, 括号中可以填入构造方法的参数,如果没有参数可以为空, 但是括号不能省。 {}中的是类的实现, 类中可以定义变量和函数。 在 val person = Person() 这句话是实例化一个对象。
上面是最简单的类的定义方法。 其实是跟python比较相似的, 甚至比python还要简洁一些。 为了加深印象, 看下python是怎么写的:
class Person():def __init__():self.name = "leo"self.age = 18def getInfo():print(f"name is {self.name}, age is {self.age}.")
if __name__ = __main__:person = Person()person.getInfo()
上面代码中的__init__是python的构造函数,可以带参数,也可以不带参数, 上面的定义中就是不带参数的。 Kotlin中也有init构造函数,而且跟python非常类似。
说几点主要不同:
- Kotlin中的 Person(), 括号里面是传入构造参数的, 上面因为我们没有传入参数, 所以是空。而python Person() 括号中是填入被继承的父类的, 至于构造参数的是在
__init__中。 - Kotlin中的 Person(), 括号里面是传入构造参数的,如果想在构造这个类的时候还想有一些逻辑处理,那就需要写init构造函数了, 一般情况下都不需要。
5.2 类的继承
最简单的继承语法是: class 类名():被继承的父类()
如我们定义一个Student类继承上面的Person类。
class Student(): Person(){fun getInfoNew() {getInfo()}
}
fun main() {val student = Student()student.getInfoNew()
}
输出
name is: leo , age is: 18.
上面的例子中可以清晰地体现继承, 继承可以继承到父类的变量和方法。
注意Kotlin的类默认不能继承, 要想能被继承, 需要用open关键字修饰
上面的类都是不带构造参数的, 但是通常我们定义的类都是带构造参数的。 带构造参数的类定义稍微复杂一些, 如下:
open class Person(val name: String, val age: Int) {fun getInfo() {print("name is: $name , age is: $age.")}
}class Student(val sex: String, name: String, age:Int): Person(name, age){fun getInfoNew() {getInfo()}
}
fun main() {val student = Student("man", "leo",18)student.getInfoNew()
}
带参数的类定义有以下几点需要注意:
- 1 构造参数需要用关键字val 或者var, 这点跟函数定义不同, 函数定义不需要这些关键字。
- 2 子类的构造函数比较要调用父类的构造函数, 因为父类Person有2个构造参数name 和age, 所以子类定义中也必须带上这2个参数。
5.3 数据类 data class
数据类算是一种特殊的类, 与一般的类相比,需要实现equals()、hashCode()、toString()这几个方法。
数据类一般都是用来定义各种数据的, 用一个类来实现方便管理。
这几个方法的实现实际上固定的模式。 所以Kotlin中已经帮我们实现好了, 只需要简单地加个data关键字就可以了。
data class myData(val brand:String, val price :Int)
fun main() {var mydata = myData("Apple", 5999)var mydata1 = myData("Huawei", 4999)println(mydata)println("mydata equal to mydata1: ${mydata==mydata1}")
}
输出:
myData(brand=Apple, price=5999)
mydata equal to mydata1: false
注意上面的 == 判断调用的就是equals() 方法。
5.4 单例类 object
单例类也是一种特殊的类, 单例类的对象在全局只能存在一个。 在Kotlin中定义单例类非常简单, 把class关键字换成object就可以了。
object Singleton {fun func1(){println("this is singleton")}
}fun main() {Singleton.func1()
}
单例类没有构造函数,因此Singleton后面不带()。
调用单例类的方法跟其他语言中调用静态方法一样, 直接用类名调用, 不需要实例化(实际上, 因为没有构造函数, 也没法实例化)。
6 其他
- 1 Kotlin的语句后面不用
; - 2 Kotlin中的双引号和单引号作用是不一样的, 字符串用双引号
相关文章:
1Kotlin基础知识
1 变量 1.1 用法 Kotlin中的变量定义有2个关键字,val和var val用来定义不可变变量,第一次赋值后就不能再被修改了, var定义可变变量, 随便修改。一个好的编程习惯是, 能用val的就不要用var, 原因是安全&a…...
Redis Lua脚本
文章目录一.引言二.eval简介三.lua数据类型和redis数据类型之间转换四.脚本的原子性五.错误处理六.纯函数脚本七.选择内部脚本一.引言 eval和evalsha命令使用内置的lua解释器,可以对lua脚本进行求值。 二.eval简介 第一个参数是一段脚本程序第二个参数是参数的个…...
web自动化测试-执行 JavaScript 脚本
JavaScript 是一种脚本语言,有的场景需要使用 js 脚本注入辅助我们完成 Selenium 无法做到的事情。 当 webdriver 遇到无法完成的操作时,可以使用 JavaScript 来完成,webdriver 提供了 execute_script() 方法来调用 js 代码。 执行 js 有两种…...
libevent笔记——简单介绍
背景 libevent libevent – an event notification library 官方定义:libevent是一个事件通知的库。更详细的介绍参考官方的就够了,这里我摘抄一下,并做一些注释 The libevent API provides a mechanism to execute a callback function whe…...
C++学习笔记-多态
多态的概念 多态的概念:通俗来说,就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会 产生出不同的状态 。 举个例子:比如 买票这个行为 ,当 普通人 买票时,是全价买票;…...
5632: 三角形
描述平面坐标系下,给定不共线的三个点组成一个三角形,问三角形最短的边长和最长的边长各为多少?输入输入包含3行,每行两个整数,表示一个点的坐标x和y。输出输出包括2个小数,分别为最短的边长和最长的边长。…...
Java基础--IO操作
一、IO原理及分类 一、IO原理 1、I/O是Input/Output的缩写,I/O技术是非常实用的技术,用于处理设备之间的数据传输,如读写文件,网络通信等。 2、java程序中对于数据的输入/输出操作一般都是以流的方式进行 3、java.io包下提供各…...
C++多线程
目录一、C线程库1. 认识thread类2. 线程函数的参数3. this_thread二、原子操作三、C互斥锁1. mutex2. lock_guard3. unique_lock四、C条件变量1. condition_variable2. 实现两个线程交替打印奇偶数一、C线程库 1. 认识thread类 在C11之前没有多线程的概念,涉及到的…...
【Arduino使用nRF24L01 】
【Arduino使用nRF24L01 】 1. 概述2. nRF24L01 收发器模块2.1工作原理2.2 NRF24L01模块变体2.3 nRF24L01 模块引脚排列3. 如何将 nRF24L01 连接到 Arduino3.1 原理接线图3.2 Arduino 和 nRF24L01 代码3.3 代码说明4. 故障排除5. 两个NRF24L01和Arduino进行双向无线通信5.1 nRF2…...
Appium自动化测试框架是一种较为优雅的使用方式
以操作小米商城下单为例流程是 启动小米商城app, 点击分类,点击小米手机, 点击小米10 至尊版,点击加入购物车,点击确定....原脚本Copyfrom time import sleep from appium import webdriver from selenium.common.exceptions impo…...
Linux c编程之应用交互协议分析与设计
在实际编程应用中,两个或多个功能服务(模块)之间 需要通过消息交互进行协作完成用户想要的逻辑功能,这里的消息交互指的是应用层的交互。最终数据传输(无论是TCP/IP还是其它)都是以二进制形式完成,但对于应用层协议来说有两种,一种是二进制协议,一种是文本协议。不管是…...
基于YOLOv5的细胞检测实战
数据及代码链接见文末 1.任务与数据集介绍 如下图所示,我们有一个医学细胞数据集,需要从数据集中检测出三种不同的细胞。标签中已经标注了细胞的类别和位置。 我们也可以看到,三种细胞有着不同的形态和颜色,同时数据集的标签也存在没有标注到的细胞 2.数据与标签配置方…...
【经典蓝牙】蓝牙AVRCP协议分析
协议简介 蓝牙AVRCP协议是蓝牙设备之间音视频的控制协议。定义了音频/视频的控制、浏览、查询、通知等一系列的命令集。常用来蓝牙耳机对手机的音乐进行控制,以及获取手机的音乐信息等场景。AVRCP协议有两个角色,分别是controller(CT&#x…...
gin 框架初始教程
一 、gin 入门1. 安装gin :下载并安装 gin包:$ go get -u github.com/gin-gonic/gin2. 将 gin 引入到代码中:import "github.com/gin-gonic/gin"3.初始化项目go mod init gin4.完整代码package mainimport "github.com/gin-go…...
对象分配策略
对象创建后,究竟何去何从,对象在堆中又会经历哪些过程,本篇就会详细解释对象创建后直到对象被回收的整个过程。之前博主已经写过Minor GC、Major GC、Full GC的区别,而本篇也主要根据这几个GC开展。 对象回收过程流程如下图所示: 正常的对象生存过程&a…...
你可能不知道的前端监控方案
前言 现有的大部分监控方案都是针对服务端的,而针对前端的监控很少,诸如线上页面的白屏时间是多少、静态资源的加载情况如何、接口请求耗时好久、什么时候挂掉了、为什么挂掉,这些都不清楚。 因而,我们需要一个前端的页面监控系…...
java spring AOP 完全注解开发
我们先创建一个项目 然后引入java spring aop的依赖 然后 在src下创建目录 我这里 直接就叫 Aop了 下面创建一个User类 参考代码如下 package Aop;import org.springframework.stereotype.Component;Component public class User {public void add(){System.out.println(&qu…...
ctf pwn基础-4
今天是学pwn的第四天,去接触了pwn的整数溢出。 目录 基础 实例讲解 实例讲解2 基础 关于整数溢出,这里以int为例,因为我php之前搞的比较多,以为这个int也是想php一样是64,最大值是9开头的那个,闹了不少笑…...
bool与引用类型
bool与引用类型bool类型介绍与使用bool(布尔类型)大小:1个字节返回值有两个:1(true),0(false)#include<iostream>using namespace std;int main() {bool a false;bool b true;cout << "a " << a << end…...
tkinter界面的TCP通信/tkinter开启线程接收TCP
前言 用简洁的语言写一个可以与TCP客户端实时通信的界面。之前做了一个项目是要与PLC进行信息交互的界面,在测试的时候就利用TCP客户端来实验,文末会附上TCP客户端。本文分为三部分,第一部分是在界面向TCP发送数据,第二部分是接收…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
Docker、Wsl 打包迁移环境
电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本: 2.2.4.0 内核版本: 5.15.153.1-2 WSLg 版本: 1.0.61 MSRDC 版本: 1.2.5326 Direct3D 版本: 1.611.1-81528511 DXCore 版本: 10.0.2609…...
