当前位置: 首页 > news >正文

Android Kotlin实战之高阶使用泛型扩展协程懒加载详解

前言:

通过前面几篇文章,我们已基本掌握kotlin的基本写法与使用,但是在开发过程中,以及一些开源的API还是会出现大家模式的高阶玩法以及问题,如何避免,接下来讲解针对原来的文章进行一些扩展,解决大家在工作中遇到的问题,如何去解决

如果还有人不了解kotlin,可以查看我的基础篇kotlin。

Android kotlin在实战过程问题总结与开发技巧详解_kotlin 同步锁_蜗牛、Z的博客-CSDN博客

Kotlin语法详解与实践教程,区分JAVA以及如何闭坑_kotlin mapof可以嵌套 to_蜗牛、Z的博客-CSDN博客

1. lazy

lazy是kotlin中的懒加载,这种写法在很多场景中都有,懒加载并不是立刻在内存中申请,而是通过lazy(),调用才会

lazy的只能是常量,用val修饰,变量是全局也可以是局部变量

通过这个lazy{}可以看出,无论你在最上面调用什么,默认值都是最后一个。通过IDE,可以提示看到ccc ^lazy,这就是懒加载的值。这个值也可以通过方法获取

 

fun a() {val aa: String by lazy {MyLog.log("val aa:String by lazy start")"aaaa""bbbb"b()}MyLog.log(aa)MyLog.log(aa)
}fun b(): String {return "aaaaa"
}

一旦懒加载对象被调用过,后期在调用将只能取到值,不会再处理其他的lazy{} 方法体。

 

注意:lazy和lateinit无法一起使用。lazy修饰val变量,lateinit修饰的是var变量。

2.lateinit

也是懒加载机制,对象是var的格式。但是,这个变量需要是全局变量,不能是局部变量。

lateinit var string: String
lateinit var people: People
fun c() {people = People()people.name = "zhangshan"string = "aaaa"MyLog.log(people.name!!)val child: People by lazy{People()}}

3.如何避免参数加"!!"可为空符号

kotlin的变量如果不是懒加载修饰,那么你在申请的时候,就要给出变量值,即默认值

常见写法:

var name:String?=null,表示当前对象是null

var title:String="title",表示已默认值、

但是如果你申请为null,那么你在赋值的时候,这个参数就要在多个地方加上"!!",否则会报错。这种写法很烦人。

如何避免?

使用懒加载机制,通过上面两个懒加载,可以避免这种问题的参数。否则你在任何地方进程参数传递都会被判为null。

4.类的扩展函数

kotlin支持在现有的类中,动态扩展函数,格式就是类对象+"."+函数名,可以支持参数和返回值,扩展的函数和正常函数一样使用

以下是对String扩展一个两个方法,分别是log()和size()


fun String.log(log:String) {MyLog.log(log)
}fun String.size(): Int {return toString().length
}

5.扩展属性、扩展变量

kotlin支持动态新增变量,格式就类名+"."+变量名+":"+类型

这种写法可以无限的扩展你需要的变量,扩展变量一样,只能在最外围,不能在方法体中定义,

扩展属性需要额外重写get()方法,且不能申请直接赋值

val String.defaulename: Stringget() {return "defaulename"}fun e() {val name=""MyLog.log(name.defaulename)
}

这里需要重写get(),给出默认值。

6.apply与let与also

apply与alse是链式设置,返回的是当前对象,let返回值是unit,

  • apply、also,闭包的返回值都是this,前者apply接受的闭包类型调用者的扩展函数,后者接受的闭包类型为 入参为调用者类型的函数;
  • also、apply,非常适合对同一个对象连续操作的链式调用;
  • run、let,闭包的返回值为最后一行非赋值代码,前者run接受的闭包类型调用者的扩展函数,后者接受的闭包类型为 入参为调用者类型的函数;
  • run、let,非常适合上一个操作返回值作用于下一个操作的调用;

我们经常会使用如下写法:

if(people!=null){peope.name="zhangshan"}

apply写法:

people?.apply{it->it.name="zhangsnan"}

7.类的初始化模块init

kotlin中没有static{}模块,是通过init{}替代了static。如果需要提前初始化的可以放在init中,常见的so库加载可以放到init中

class Example {init {//init module}
}

8 .接口多继承,方法名冲突

 如果接口中有两个相同的方法名,在java中是需要修改一个的。在kotlin中就可以避免这种。只要在继承方法中,指向各个类的即可。


class TestInterface : IntFacA, IntFacB {override fun log() {super<IntFacA>.log()super<IntFacB>.log()}override fun info() {}
}

9.internal 介绍

internal 属于修饰,和provite、public、protect一样

  • private 意味着只在这个类内部(包含其所有成员)可见;
  • protected—— 和 private一样 + 在子类中可见。
  • internal —— 能见到类声明的 本模块内 的任何客户端都可见其 internal 成员;
  • public —— 能见到类声明的任何客户端都可见其 public 成员。

10.数据类(data)

将类对象修饰成data,需要的变量直接在构造器中申明,不需要方法体

data class User(val name: String = "", val age: Int = 0)

11.密封类(sealed)

密封类用来表示受限的类继承结构:当一个值为有限几种的类型、而不能有任何其他类型时。在某种意义上,他们是枚举类的扩展:枚举类型的值集合也是受限的,但每个枚举常量只存在一个实例,而密封类的一个子类可以有可包含状态的多个实例。

要声明一个密封类,需要在类名前面添加 sealed 修饰符。虽然密封类也可以有子类,但是所有子类都必须在与密封类自身相同的文件中声明

sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()

一个密封类是自身抽象的,它不能直接实例化并可以有抽象(abstract)成员。

密封类不允许有非-private 构造函数(其构造函数默认为 private)。

fun eval(expr: Expr): Double = when(expr) {is Const -> expr.numberis Sum -> eval(expr.e1) + eval(expr.e2)NotANumber -> Double.NaN// 不再需要 `else` 子句,因为我们已经覆盖了所有的情况
}

类似接口继承,通过泛型来判断

12.泛型,通配符类型参数:in 和 out

在开发过程中,泛型的利用,可以很好的解决代码臃肿问题,也能很好的进行解耦。在kotlin中,泛型的使用有普通的,也有通配符限定

1.正常泛型

interface Factory<T> {fun getEntity(): T
}class Room : Factory<String> {override fun getEntity(): String {return "String info"}
}

这种是我们最常见的泛型,通过泛型,可以很好的获取不同的对象类型

2通配符 out和in

java中也有通配符,? extend E,? extends E 表示此方法接受 E 或者 E 的 一些子类型对象的集合,而不仅仅是 E 自身。简而言之,带 extends 限定(上界)的通配符类型使得类型是协变的。

还有一种,? super String,表示只接收String类型。

在 kotlin 语言中,out 表示协变,in 表示逆变;

kotlin 中的 “out T” 等同于 Java 的 “?extends T”

kotlin 中的 “in T” 等同于 Java 的 “?super T”

也就是上线和下线。

13.嵌套类

内部类可以直接使用,就是通过最外层类引用即可,也可以单独使用

class Student {lateinit var name: Stringclass Classmate {lateinit var name: String}
}fun main() {var mate=Student.Classmate()mate.name="zhangsan"MyLog.log(mate.name)
}

14.内部类:inner 

标记为 inner 的嵌套类能够访问其外部类的成员。内部类会带有一个对外部类的对象的引用。

class Student {lateinit var name: Stringinner class Classmate {lateinit var name: String}
}fun main() {var mate=Student().Classmate()mate.name="zhangsan"MyLog.log(mate.name)
}

15.匿名内部类:

使用对象表达式创建匿名内部类实例:

window.addMouseListener(object : MouseAdapter() {override fun mouseClicked(e: MouseEvent) { …… }override fun mouseEntered(e: MouseEvent) { …… }
})

接口的监听:

1.lambda表达式

 

2.object匿名内部类

   view.setOnClickListener(object :View.OnClickListener{override fun onClick(v: View?) {}})

16.枚举类

枚举类的最基本的用法是实现类型安全的枚举,kotlin枚举有一下几种

1.支持匿名类

2.支持参数扩展

enum class MyEmu {ONE{var size="123"},TWO,THREE
}enum class MyEmu1(tag:Int) {ONE(1),TWO(2),THREE(3)
}

如果你想弄那么复杂,就当普通枚举使用

3、枚举类型新增接口

enum class MyEmu :MyInfo{ONE{override fun log() {TODO("Not yet implemented")}},TWO{override fun log() {TODO("Not yet implemented")}}
}
interface MyInfo {fun log();
}

如果枚举类型实现了接口,那么枚举中的任何元素的都变成了匿名内部类,都要实现接口的方法

17.open超类

如果一个类无法被继承,就可以将该类通过open修饰,如果类中的变量无法使用,也可以通过open修饰。

open class MyNAME {open var name = ""
}

18.静态类:object 

静态类,是通过object修饰,该类里面的所有变量和方法都是静态。且不在需要class修饰

object staticName {var name = ""fun log() {}
}

19.伴生对象

伴随对象是在普通类中进行扩展一个对象出来的,该伴生对象的成员可通过只使用类名作为限定符来调用

class BanshengObject {companion object {var name = ""fun log() {}}
}fun main() {BanshengObject.log()BanshengObject.name
}

请注意,即使伴生对象的成员看起来像其他语言的静态成员,在运行时他们仍然是真实对象的实例成员

如果使用 @JvmStatic 注解,你可以将伴生对象的成员生成为真正的静态方法和字段

20.类型别名:typealias

        类型别名为现有类型提供替代名称。 如果类型名称太长,你可以另外引入较短的名称,并使用新的名称替代原类型名。

class Alias {inner class MyStudent(name:String)
}typealias Alias_MyStudent = Alias.MyStudenttypealias SetString=Set<String>
typealias MyHandler = (Int, String, Any)->Voidfun main() {var m:MyHandler}

这个别名使用在kotlin有很多,kotlin对java的api进行封装,就是通过别名完成。也可以支持方法的别名

21.内联类

内联类必须含有唯一的一个属性在主构造函数中初始化。在运行时,将使用这个唯一属性来表示内联类的实例

inline class InlinerBean(val title:String) {val length: Intget() = title.length
}fun main() {val  bean=InlinerBean("this is inline class")}

// 不存在 'InlinerBean' 类的真实实例对象
// 在运行时,'InlinerBean' 仅仅包含 'String' 

 val  bean=InlinerBean("this is inline class")

同时,内联是为了解决额外的堆内存分配问题。

内联类支持普通类中的一些功能。特别是,内联类可以声明属性与函数

内联函数,有且仅有一个构造参数

内联函数也可以当普通函数使用,可以实现接口

22.委托:by

委托模式已经证明是实现继承的一个很好的替代方式, 而 Kotlin 可以零样板代码地原生支持它

interface Base {val message: Stringfun print()
}class BaseImpl(val x: Int) : Base {override val message = "BaseImpl: x = $x"override fun print() { println(message) }
}class Derived(b: Base) : Base by b {// 在 b 的 `print` 实现中不会访问到这个属性override val message = "Message of Derived"
}fun main() {val b = BaseImpl(10)val derived = Derived(b)derived.print()println(derived.message)
}

注意,以这种方式重写的成员不会在委托对象的成员中调用 ,委托对象的成员只能访问其自身对接口成员实现。

23.委托属性

有一些常见的属性类型,虽然我们可以在每次需要的时候手动实现它们, 但是如果能够为大家把他们只实现一次并放入一个库会更好。例如包括:

  • 延迟属性(lazy properties): 其值只在首次访问时计算;
  • 可观察属性(observable properties): 监听器会收到有关此属性变更的通知;
  • 把多个属性储存在一个映射(map)中,而不是每个存在单独的字段中。

为了涵盖这些(以及其他)情况,Kotlin 支持 委托属性:

class Example {var p: String by Delegate()
}

语法是: val/var <属性名>: <类型> by <表达式>。在 by 后面的表达式是该 委托, 因为属性对应的 get()(与 set())会被委托给它的 getValue() 与 setValue() 方法。 属性的委托不必实现任何的接口,但是需要提供一个 getValue() 函数(与 setValue()——对于 var 属性)

class Delegate {operator fun getValue(thisRef: Any?, property: KProperty<*>): String {return "$thisRef, thank you for delegating '${property.name}' to me!"}operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {println("$value has been assigned to '${property.name}' in $thisRef.")}
}

分析:

by是ReadOnlyProperty的连接,

public fun interface ReadOnlyProperty<in T, out V> {/*** Returns the value of the property for the given object.* @param thisRef the object for which the value is requested.* @param property the metadata for the property.* @return the property value.*/public operator fun getValue(thisRef: T, property: KProperty<*>): V
}

所有我们在属性委托时,需要实现 public operator fun getValue(thisRef: T, property: KProperty<*>): V

所以定义属性委托必须要实现接口ReadOnlyProperty

实战:

在jetpack的datastore中,也提供了属性委托。

    val Context.dataStore: DataStore<Preferences> by preferencesDataStore("my_datastore",produceMigrations = { it ->listOf(SharedPreferencesMigration(it, "sp_test"))})

24.Lambda 表达式

lambda 表达式与匿名函数是“函数字面值”,即未声明的函数, 但立即做为表达式传递

max(strings, { a, b -> a.length < b.length })

函数 max 是一个高阶函数,它接受一个函数作为第二个参数。 其第二个参数是一个表达式,它本身是一个函数,如下:

fun compare(a: String, b: String): Boolean = a.length < b.length

Lambda 表达式语法

Lambda 表达式的完整语法形式如下:

val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }

lambda 表达式总是括在花括号中, 完整语法形式的参数声明放在花括号内,并有可选的类型标注, 函数体跟在一个 -> 符号之后

val sum = { x: Int, y: Int -> x + y }
    val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }sum(2,3)val add = { x: Int, y: Int -> x + y }add(2,3)

从 lambda 表达式中返回一个值

ints.filter {val shouldFilter = it > 0 shouldFilter
}ints.filter {val shouldFilter = it > 0 return@filter shouldFilter
}

25.构造集合

在开发过程中,发现使用集合都需要指定泛型,还有一种可以指定一个默认值,后面所有的集合都是这种

val numbersSet = setOf("one", "two", "three", "four")
val emptySet = mutableSetOf<String>()

26.空集合

还有用于创建没有任何元素的集合的函数:emptyList()、emptySet() 与 emptyMap()。 创建空集合时,应指定集合将包含的元素类型。

27.具体类型构造函数

要创建具体类型的集合,例如 ArrayList 或 LinkedList,可以使用这些类型的构造函数。 类似的构造函数对于 Set 与 Map 的各实现中均有提供

val linkedList = LinkedList<String>(listOf("one", "two", "three"))
val presizedSet = HashSet<Int>(32)

28.集合加减法

我们正常使用逻辑都是对于变量运算,但是在kotlin中的集合也可以使用

 val plusList = numbers + "five"val minusList = numbers - listOf("three", "four")val minusList2 = numbers - "three"println(plusList)println(minusList)println(minusList2)

29.集合数据分组

Kotlin 标准库提供用于对集合元素进行分组的扩展函数。 基本函数 groupBy() 使用一个 lambda 函数并返回一个 Map。 在此 Map 中,每个键都是 lambda 结果,而对应的值是返回此结果的元素 List。 例如,可以使用此函数将 String 列表按首字母分组。 

 

val numbers = listOf("one", "two", "three", "four", "five")println(numbers.groupBy { it.first().toUpperCase() })

30.协程

Kotlin 是一门仅在标准库中提供最基本底层 API 以便各种其他库能够利用协程的语言。与许多其他具有类似功能的语言不同,async 与 await 在 Kotlin 中并不是关键字,甚至都不是标准库的一部分。此外,Kotlin 的 挂起函数 概念为异步操作提供了比 future 与 promise 更安全、更不易出错的抽象。

kotlinx.coroutines 是由 JetBrains 开发的功能丰富的协程库。它包含本指南中涵盖的很多启用高级协程的原语,包括 launch、 async 等等。


 

在kotlin中,suspend修饰的方法叫着协程。目前针对协程有一下几种

1.同步:runBlocking:

2.异步:kotlinx-coroutines-core库

 代码库:

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1"

class MySuspendMain {suspend fun info() {}
}fun main() {GlobalScope.launch { // 在后台启动一个新的协程并继续delay(1000L) // 非阻塞的等待 1 秒钟(默认时间单位是毫秒)println("World!") // 在延迟后打印输出}println("Hello,") // 协程已在等待时主线程还在继续Thread.sleep(2000L) // 阻塞主线程 2 秒钟来保证 JVM 存活runBlocking {val mains=MySuspendMain()mains.info()}}

由于kotlinx-coroutines-core库很大,我会出一篇详细的文章讲解。

相关文章:

Android Kotlin实战之高阶使用泛型扩展协程懒加载详解

前言&#xff1a; 通过前面几篇文章&#xff0c;我们已基本掌握kotlin的基本写法与使用&#xff0c;但是在开发过程中&#xff0c;以及一些开源的API还是会出现大家模式的高阶玩法以及问题&#xff0c;如何避免&#xff0c;接下来讲解针对原来的文章进行一些扩展&#xff0c;解…...

数字映射:数字孪生技术的应用场景及作用

对于许多行业来说&#xff0c;数字孪生技术是未来。数字孪生定义数字孪生不仅仅是某物的副本或克隆&#xff0c;它是对象或系统的动态实时表示。数字孪生是一种虚拟模型&#xff0c;旨在准确反映物理对象。是物理对象、流程、服务或环境的数字表示&#xff0c;其行为和外观与现…...

配置二层远程端口镜像案例

实验拓扑&#xff1a; 实验需求&#xff1a; 如图1所示&#xff0c;某公司行政部通过SwitchA与外部Internet通信&#xff0c;监控设备Server通过SwitchB与SwitchA相连。 现在希望Server能够远程对行政部访问Internet的流量进行监控。 操作步骤&#xff1a; 配置观察端口 # 在…...

Linux-0.11 kernel目录fork.c详解

Linux-0.11 kernel目录fork.c详解 fork.c中主要实现内核对于创建新的进程的行为。其中copy_process是其最核心的函数。 copy_process int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,long ebx,long ecx,long edx,long fs,long es,long ds,long eip,…...

如何或者无插件Web页面监控播放软件LiveNVR的固定视频流地址,实现大屏上墙、播放、视频分析等目的

1、LiveNVR介绍 LiveNVR的安防监控的视频直播&#xff0c;可以按标准的Onvif/RTSP协议接入监控设备&#xff0c;也可以通过海康、大华、天地伟业等厂家私有SDK接入监控&#xff0c;实现web页面的播放和录像回放。 可以分发HTTP-FLV、WS-FLV、WebRTC、RTMP、HLS(M3U8)、RTSP等多…...

postman断言脚本(2)

https://learning.postman.com/docs/writing-scripts/script-references/test-examples/#parsing-response-body-data状态码pm.test("Status code is 200",function(){pm.response.to.have.status(200);});pm.test("Status code is 200",()>{pm.expect(…...

js中?.、??的具体用法

1、?. &#xff08;可选链运算符&#xff09; 在javascript中如果一个值为null、undefined&#xff0c;直接访问下面的属性&#xff0c; 会报 Uncaught TypeError: Cannot read properties of undefined 异常错误。 而在真实的项目中是会出现这种情况&#xff0c;有这个值就…...

刷题笔记1 | 704. 二分查找,27. 移除元素

704. 二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 输入: nums [-1,0,3,5,9,12], target 9 输出: 4 …...

柔性电路板的优点、分类和发展方向

柔性电路板是pcb电路板的一种&#xff0c;又称为软板、柔性印刷电路板&#xff0c;主要是由柔性基材制作而成的一种具有高可靠性、高可挠性的印刷电路板&#xff0c;具有厚度薄、可弯曲、配线密度高、重量轻、灵活度高等特点&#xff0c;主要用在手机、电脑、数码相机、家用电器…...

OpenCV入门(二)快速学会OpenCV1图像基本操作

OpenCV入门&#xff08;一&#xff09;快速学会OpenCV1图像基本操作 不讲大道理&#xff0c;直接上干货。操作起来。 众所周知&#xff0c;OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大。今天就从读取图片&#xff0c;显示图片&#xff0c;输出图片信息和简单的…...

Redis源码---有序集合为何能同时支持点查询和范围查询

目录 前言 Sorted Set 基本结构 跳表的设计与实现 跳表数据结构 跳表结点查询 跳表结点层数设置 哈希表和跳表的组合使用 前言 有序集合&#xff08;Sorted Set&#xff09;是 Redis 中一种重要的数据类型&#xff0c;它本身是集合类型&#xff0c;同时也可以支持集合中…...

从计费出账加速的设计谈周期性业务的优化思考

1号恐惧症 你有没有这样的做IT的朋友&#xff1f;年纪轻轻&#xff0c;就头发花白或者秃顶&#xff0c;然后每个月周期性的精神不振&#xff0c;一到月底&#xff0c;就有明显的焦虑。如果有&#xff0c;他可能就是运营商行业做计费运营的&#xff0c;请对他好点&#xff0c;特…...

垃圾回收的概念与算法(第四章)

《实战Java虚拟机&#xff1a;JVM故障诊断与性能优化 (第2版)》 第4章 垃圾回收的概念与算法 目标&#xff1a; 了解什么是垃圾回收学习几种常用的垃圾回收算法掌握可触及性的概念理解 Stop-The-World&#xff08;STW&#xff09; 4.1. 认识垃圾回收 - 内存管理清洁工 垃圾…...

让您的客户了解您的制造过程“VR云看厂实时数字化展示”

一、工厂云考察&#xff0c;成为市场热点虚拟现实&#xff08;VR&#xff09;全景技术问世已久&#xff0c;但由于应用范围较为狭窄&#xff0c;一直未得到广泛应用。国外客户无法亲自到访&#xff0c;从而导致考察难、产品取样难等问题&#xff0c;特别是对于大型制造企业来说…...

CV——day80 读论文:DLT-Net:可行驶区域、车道线和交通对象的联合检测

DLT-Net:可行驶区域、车道线和交通对象的联合检测I. INTRODUCTIONII. ANALYSIS OF PERCEPTIONIV. DLT-NETA. EncoderB. Decoder1) Drivable Area Branch(可行驶区域分支)2) Context Tensor(上下文张量)3) Lane Line Branch(车道线分支)4) Traffic Object Branch(目标检测对象分…...

工具篇4.5数据可视化工具大全

1.1 Flourish 数据可视化不仅是一项技术&#xff0c;也是一门艺术。当然&#xff0c;数据可视化的工具也非常多&#xff0c;仅 Python 就有 matplotlib、plotly、seaborn、bokeh 等多种可视化库&#xff0c;我们可以根据自己的需要进行选择。但不是所有的人都擅长写代码完成数…...

京东前端二面常考手写面试题(必备)

实现发布-订阅模式 class EventCenter{// 1. 定义事件容器&#xff0c;用来装事件数组let handlers {}// 2. 添加事件方法&#xff0c;参数&#xff1a;事件名 事件方法addEventListener(type, handler) {// 创建新数组容器if (!this.handlers[type]) {this.handlers[type] …...

如何用AST还原某音的JSVMP

1. 什么是JSVMP vmp简单来说就是将一些高级语言的代码通过自己实现的编译器进行编译得到字节码&#xff0c;这样就可以更有效的保护原有代码&#xff0c;而jsvmp自然就是对JS代码的编译保护&#xff0c;具体的可以看看H5应用加固防破解-JS虚拟机保护方案。 如何区分是不是jsv…...

【蓝桥杯试题】 递归实现指数型枚举例题

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 &#x1f91e; 作者&#xff1a;那就叫我亮亮叭 &#x1f4d5; 专栏&#xff1a;蓝桥杯试题 文章目录1. 题目描述2. 思路解释2.1 时间复杂度2.2 递归3. 代码展示最后&#x…...

【用Group整理目录结构 Objective-C语言】

一、接下来,我们看另外一个知识点,怎么用Group把这一堆乱七八糟的文件给它整理一下,也算是封装一下吧, 1.这一堆杂乱无章的文件: 那么,哪些类是属于模型呢,哪些类是属于视图呢,哪些类是属于控制器呢, 我们接下来通过Group的方式,来给它们分一下类, 这样看起来就好…...

JavaScript高级程序设计读书分享之8章——8.1理解对象

JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 创建自定义对象的通常方式是创建 Object 的一个新实例&#xff0c;然后再给它添加属性和方法。 let person new Object() person.name Tom person.age 18 person.sayName function(){//示 this.name…...

代码随想录算法训练营第四十天 | 343. 整数拆分,96.不同的二叉搜索树

一、参考资料整数拆分https://programmercarl.com/0343.%E6%95%B4%E6%95%B0%E6%8B%86%E5%88%86.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1Mg411q7YJ不同的二叉搜索树https://programmercarl.com/0096.%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BA%8C%E5%8F%89%E6%90…...

数据结构与算法系列之顺序表的实现

这里写目录标题顺序表的优缺点&#xff1a;注意事项test.c&#xff08;动态顺序表&#xff09;SeqList.hSeqList.c各接口函数功能详解void SLInit(SL* ps);//定义void SLDestory(SL* ps);void SLPrint(SL* ps);void SLPushBack(SL* ps ,SLDataType * x );void SLPopBack(SL* ps…...

基于Linux_ARM板的驱动烧写及连接、挂载详细过程(附带驱动程序)

文章目录前言一、搭建nfs服务二、ARM板的硬件连接三、putty连接四、挂载共享文件夹五、烧写驱动程序六、驱动程序示例前言 本文操作环境&#xff1a;Ubuntu14.04、GEC6818 这里为似懂非懂的朋友简单叙述该文章的具体操作由来&#xff0c;我们的主要目的是将写好的驱动程序烧进…...

python-爬虫-字体加密

直接点 某8网 https://*****.b*b.h*****y*8*.com/ 具体网址格式就是这样的但是为了安全起见,我就这样打码了. 抛出问题 我们看到这个号码是在页面上正常显示的 F12 又是这样就比较麻烦,不能直接获取.用requests库也是获取不到正常想要的 源码的,因为字体加密了. 查看页面源代码…...

计算机组成原理4小时速成5:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线

计算机组成原理4小时速成5&#xff1a;输入输出系统&#xff0c;io设备与cpu的链接方式&#xff0c;控制方式&#xff0c;io设备&#xff0c;io接口&#xff0c;并行串行总线 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c…...

安全狗受聘成为福州网信办网络安全技术支撑单位

近日&#xff0c;福州市委网信办召开了2022年度网络安全技术支撑单位总结表彰大会。 作为国内云原生安全领导厂商&#xff0c;安全狗也出席了此次活动。 据悉&#xff0c;会议主要对2022年度优秀支撑单位进行表彰&#xff0c;并为2023年度支撑单位举行授牌仪式。 本次遴选工…...

RV1126 在Ubuntu18.04开发环境搭建

1:安装软件终端下输入安装命名&#xff1a;sudo apt install openssh-serversudo apt install android-tools-adbsudo apt install vim net-tools gitsudo apt install cmakesudo apt install treesudo apt install minicomsudo apt install gawksudo apt install bisonsudo ap…...

如何在 C++ 中调用 python 解析器来执行 python 代码(一)?

实现 Python UDF 中的一步就是学习如何在 C 语言中调用 python 解析器。本文根据 Python 官方文档做了一次实验&#xff0c;记录如下&#xff1a; 1. 安装依赖包 $sudo yum install python3-devel.x86_642. 使用 python-config 来生成编译选项 $python3.6-config --cflags -…...

操作系统权限提升(二十三)之Linux提权-通配符(ws)提权

系列文章 操作系统权限提升(十八)之Linux提权-内核提权 操作系统权限提升(十九)之Linux提权-SUID提权 操作系统权限提升(二十)之Linux提权-计划任务提权 操作系统权限提升(二十一)之Linux提权-环境变量劫持提权 操作系统权限提升(二十二)之Linux提权-SUDO滥用提权 利用通配符…...

网站算阵地建设/百度关键词屏蔽

主要分以下步骤&#xff1a; 1&#xff09;关闭sendmail 2)用yum安装bind-*即DNS的配置 3&#xff09;yum安装postfix,配置其主配置文件/etc/postfix/main.cf 4&#xff09;安装cyrus-sasl,配置/etc/sysconfig/saslauthd 5)安装dovecot并进行配置 6&#xff09;安装cyrus-imapd…...

行业网站导航/seo百度关键词优化

说明&#xff1a;点击下方论文链接可跳转到 微信论文解读页面 隐函数三维重建 Implicit Functions in Feature Space for 3D Shape Reconstruction and Completion Dynamic Neural Radiance Fields for Monocular 4D Facial Avatar Reconstruction Neural Body: Implicit …...

wordpress更改后台/网站百度关键词排名软件

Linux作系统实验四淮海工学院计算机工程学院实验报告书课程名&#xff1a;《网络操作系统》题 目&#xff1a; SHELL程序设计班 级&#xff1a; 网路122学 号&#xff1a;姓 名&#xff1a;一、目的与要求掌握SHELL程序设计方法和技术。二、实验内容与题目用Shell编程&#xff…...

网站关键词排名优化技巧/免费网页制作网站

需要全部代码或者更多前端学习资料的可以私信我“前端”&#xff0c;自动回复。今天是520。一句温柔的问候&#xff0c;一束美丽的鲜花&#xff0c;一段真情的告白。但是作为一名与众不同的程序员&#xff0c;我们可不仅仅拥有上面的传情方法&#xff0c;别忘了每个人的手上可是…...

建站宝盒源码/报个电脑培训班要多少钱

1 引言 1.1 编写目的 为更好地规范Jboss软件安装&#xff0c;促进安装标准化而编写该文档。 2 JBOSS安装 2.1 安装JDK 选择安装JDK的版本&#xff1a; 核心系统&#xff1a;jdk-1_5_0_22-linux-amd64.bin其它系统&#xff1a;jdk-6u45-linux-x64财务用WAS自带的JDK&#xff08…...

用卡通人物做网站属于侵权吗/百度提交网址多久才会收录

满意答案nico402013.08.18采纳率&#xff1a;53% 等级&#xff1a;12已帮助&#xff1a;6620人200分是一个诱惑&#xff01;-------------------------------------------------------你的问题描述有问题。回答者“tbsoo_com ”的计算这里$i-1是错误的&#xff0c;应该加上括…...