Kotlin
- Object & class
Kotlin中的object和class的主要区别在于:object用于创建单例,而class用于创建多个实例。 object关键字用于声明一个全局唯一的实例,而class用于声明可以创建多个实例的类。
在Kotlin中,object声明的是一个单例对象,它只能在全局范围内被访问一次。单例对象在第一次使用时才会被创建,之后就会一直存在,直到程序结束。单例对象不能声明构造函数,因为它们只有一个实例,无需手动创建
object
object Demo {
fun printMessage() {
println("This is a demo message")
}
}
Demo.printMessage() // 输出: This is a demo message
class ( 所有的类默认修饰为 public final,需要被继承添加修饰 open/实际上是移除了final)
class Person(val name: String, val age: Int) {
fun greet() {
println("Hello, my name is $name and I am $age years old.")
}
}
val person1 = Person("Alice", 30)
val person2 = Person("Bob", 25)
person1.greet() // 输出: Hello, my name is Alice and I am 30 years old.
person2.greet() // 输出: Hello, my name is Bob and I am 25 years old.
- val :只读,不是常量
val num:Int = 0
- var :可读可写
var num:Int = 0
- when (面向枚举的程序思想)
举个栗子: 无论什么动作都可以这么设计,集成功能模块管理
方案 1
enum class SetComposeUI{
NavigationUI,
ListUI,
BottomUI
}
@Composable
fun FetchUI(set:SetComposeUI){
when(set){
SetComposeUI.NavigationUI -> Greeting(name = "World")
SetComposeUI.ListUI -> TODO()
SetComposeUI.BottomUI -> TODO()
}
}
方案 2
object FetchUIForInCall {
// @androidx.compose.runtime.Composable
var callUI = @Composable{ set:SetComposeUI ->
when(set){
SetComposeUI.NavigationUI -> Greeting(name = "world")
SetComposeUI.ListUI -> TODO()
SetComposeUI.BottomUI -> TODO()
else -> {}
}
}
}
使用
// 这个函数只是为了模拟MainActivity的setContent
@Composable
fun FetchContextUI() {
FetchUIForInCall.callUI(SetComposeUI.NavigationUI)
}
- inline
记住一点:如果函数的参数是函数,那么就使用inline (减少性能损耗)
或者使用单例 Object 去 创建 fun
- indexOf
const val message = "Lina一起去白嫖吗?"
val indexSet = message.indexOf('嫖')
val info = message.substring(0, indexSet)
- :: 引用函数
object FetchShared {
inline fun loadData(content:(Any)->Unit){
/*
val map = Net Request
* */
val map = "Net Request"
content(map)
}
}
class MessageManager {
fun sendMessage(any:Any):Unit{
println("$any")
// 回到主线程绑定数据更新UI
}
init {
// 使用
FetchShared.loadData(::sendMessage)
}
}
- Regex (打乱加密)
val password = "Parameter 'url' is never used"
// 加密操作
val newPwd = password.replace(Regex("[abcd]")) {
when(it.value){
"a" -> "9"
"b" -> "5"
"c" -> "2"
"d" -> "7"
else -> ""
}.toString()
}
// 揭秘操作
val sourcePwd = newPwd.replace(Regex("[9527]")){
when(it.value) {
"9" -> "a"
"5" -> "b"
"2" -> "c"
"7" -> "d"
else -> ""
}.toString()
}
- == (值比较)
val lina1 = "xiong_xiao"
val lina2 = "xiong_da"
val os = lina1 == lina2
- === (引用比较)是不是指向同一块内存地址
val ros = lina1 === lina2
- forEach
fun fetchMap(){
lina1.forEach {
println(it)
}
}
- toIntOrNull
var countSize:Int? = null
fun fetchCountSize(){
// 如果没有赋值成功直接给null,避免程序崩溃
countSize = "9527.0".toIntOrNull()
}
- roundToInt
val positionX:Double = 9999.6666
val positionY:Double = 9999.4666
fun doubleToInt(){
val cureentX = positionX.roundToInt() // 四舍五入:值10000
val currentY = positionY.roundToInt() // 四舍五入:值9999
}
- takeIf
true 返回自身,false 返回null
val takeIfX = positionX.takeIf { it > 20000 }
- takeUnless
true 返回null,false 返回自身
isNullOrBlank:用于判断一个字符串是否为空或仅包含空格。 如果字符串为null、空字符串或仅包含空格,则返回true;否则返回false
val takeUnlessX = positionX.toString().takeUnless { it.isNullOrBlank() } ?: "未初始化"
- mutator (+= -= 操作)
val list = mutableListOf("hong","lina","yxm")
list += "xx"
list += "lyx"
list += "ll"
list -= "lyx"
println(list)
- removeIf true删除 false保留
val list = mutableListOf("hong","lina","yxm")
list += "xx"
list += "lyx"
list += "ll"
list -= "lyx"
println(list)
val googleX = true
// 删除所有
list.removeIf { googleX }
// 删除ll
list.removeIf { it == "ll" }
- list 🏪 遍历
for (name in list) {
println(name)
}
list.forEach {
println(it)
}
list.forEachIndexed { index, value ->
println("index of $index/ value of $value")
}
- list 索引安全
elementAtOrElse:当索引越界时,elementAtOrElse会返回一个默认值。这个默认值是通过一个lambda表达式提供的,类似于Swift的guard
elementAtOrNull在索引越界时返回null。这意味着它不会提供一个默认值,而是直接返回null来表示索引越界的情况
list.elementAtOrElse(100) { 69 } // 不存在返回默认值
list.elementAtOrNull(100) // 不存在返回null
list.elementAtOrNull(666)?:"list 越界了"
- set
去重
list.add("ll")
list.add("ll")
list.add("lina")
// 去重并保证排序
var lists = list.toSortedSet().toList()
交集/并集/差集
val listSet1 = list.toSortedSet()
list.add("lina/hong")
val listSet2 = list.toSortedSet()
// 交集
val intersectionSet = listSet1.intersect(listSet2)
// 并集
val unionSet1 = listSet1 + listSet2
val unionSet2 = listSet1.union(listSet2)
// 差集
val differentSet1 = listSet2 - listSet1
val differentSet2 = listSet2.subtract(listSet1)
- map
val toMap1 = mapOf("lina" to(28),"yxm" to(36))
val toMap2 = mapOf(Pair("lina",28),Pair("yxm",36))
// 获取value的方式
val value1 = toMap2["lina"]
val value2 = toMap2.get("lina")
// 不推荐使用 value1 和 value2 的获取方式(下面的强咧推荐)
val value3 = toMap2.getOrDefault("lina",toMap2.get("yxm"))
val value4 = toMap2.getOrElse("lina"){666}
// map.getOrPut
val mutableMap = mutableMapOf("lina" to ("好小啊"),"yxm" to ("好大啊"))
// map、添加元素可以用下标["lina"] = 24,或者 map.put("lina",24) 推荐下面的方式,毕竟我们都喜欢下面:
val elementOfMap = mutableMap.getOrPut("lina"){"哇涩,好小啊"}
// getOrPut 的好处是如果没有找到key,会帮你自动添加到map中,然后在帮你从map中取出值来
- 计算属性
取1-1000 随机值
val phoneNumber:Int = (1..1000).shuffled().first().also { it }
- data class
数据类是专门用于描述数据的类,通常用于存储和传输数据,而不涉及任何业务逻辑
data class Person(val name: String, val age: Int)
- apply let run with also
在Kotlin中,apply,let,run,also, with 都是作用域函数,用于控制代码块的执行以及简化代码
- apply
val resultPro1 = "Text".apply {// this:String
this + "null"
666 + 666
66.0 + 66.0 // also 返回值永远是调用apply的类型,不会改变
}
- let
val resultPro2 = "Text".let {// it:String
it + "null"
666 + 666
66.0 + 66.0// let 返回值的类型永远在最后一行的类型
}
- run
val resultPro3 = "Text".run {// this:String
this + "null"
666 + 666
66.0 + 66.0 // run 返回值的类型永远在最后一行的类型
}
- also
val resultPro4 = "Text".also {// it:String
it + "null"
666 + 666
66.0 + 66.0 // also 返回值永远是调用also的类型,不会改变
}
- with
val resultPro5 = with("Text") {// this:String
this + "null"
666 + 666
66.0 + 66.0// with 返回值的类型永远在最后一行的类型
}
- lateinit (未完成初始化,调用的时候在给赋值,加载到内存)
loadDataFlow函数被创建的时候马上执行
- lazy (初始化完成之后调用的时候在加载到内存)
loadDataFlow函数不会马上执行,调用lazy属性的时候才回去执行
fun loadDataFlow(){
println("开始加载数据")
println("正在加载数据")
println("正在加载数据")
println("正在加载数据")
println("结束加载数据")
}
---------------------------------
fun gotoLoad(){
// TODO lateinit
lateinit var requestNet1:Any
requestNet1 = loadDataFlow() // 程序跑到这里,创建即执行
// TODO lazy
val requestNet2 by lazy { loadDataFlow() } // 程序跑到这里,不执行,调用时才去执行
}
- is & as
open class MyText(var text:String? = null,var setTextColor:String? = null,var textSize:Float? = null)
class MyTextView(isShow:Boolean):MyText()
val textView:MyText = MyTextView(isShow = true)
if (textView is MyTextView) textView as MyTextView
if (textView is MyText) textView as MyText
- require (相当于Swift的guard)
require(true){
// false 执行这里
}
thank。。。持续更新中...