Kotlin基础知识5
定义类与field关键字
class test {var name = "Derry"get() = fieldset(value) {field = value}/* 背后做的事情:会转换成下面的java代码@NotNullprivate String name = "Derry";public void setName( @NotNull String name) {this.name = name;}@NotNullpublic String getName() {return this.name;}//因此,如果定义方法的时候,不要定义setName和getName,会冲突*/var value = "ABCDEFG"// 下面的隐式代码,不写也有,就是下面这个样子get() = fieldset(value) {field = value}var info = "abcdefg ok is success"get() = field.capitalize() // 把首字母修改成大写set(value) {field = "**【$value】**"}//如果set方法为private,那么setInfo就为private/* 背后做的事情:@NotNullprivate String info = "abcdefg ok is success";public void setInfo( @NotNull String info) {this.info = "**【" + info + "】**";}@NotNullpublic String getInfo() {return StringKt.capitalize(this.info)}*/
}fun main() {// 背后隐式代码:new test().setName("Kevin");test().name = "Kevin"// 背后隐式代码:System.out.println(new test().getName());println(test().name)println(">>>>>>>>>>>>>>>>>>")// 背后隐式代码:System.out.println(new test().getInfo());println(test().info)// 背后隐式代码:new test().setInfo("学习KT");test().info = "学习KT"
}
计算属性
class testclass {val number : Int = 0/* 背后的代码:private int number = 0;public int getNumber() {return this.number;}*/// 计算属性 下面这样写 get函数覆盖了 field 内容本身,相当于field失效了,无用了,以后用不到了val number2 : Intget() = (1..1000).shuffled().first() // 从1到1000取出随机值 返回给 getNumber2()函数/*背后隐式代码:当转换成java代码时为什么没有看到 number2 属性定义?答:因为属于 计算属性 的功能,根本在getNumber2函数里面,就没有用到 number2属性,所以 number2属性 失效了,无用了,以后用不到了public int getNumber2() {return (1..1000).shuffled().first()java的随机逻辑 复杂 ;}*/var info: String ? = null // ""// 防范竞态条件 当你调用成员,这个成员,可能为null,可能为空值,就必须采用 防范竞态条件,这个是KT编程的规范化fun getShowInfo() : String {// 这个成员,可能为null,可能为空值,就启用 防范竞态条件// 这种写法,就属于 防范竞态条件,我们可以看到专业的KT开发者,有大量这种代码// also永远都是返回 info本身return info?.let {if (it.isBlank()) {"info你原来是空值,请检查代码..." // 是根据匿名函数最后一行的变化而变化} else {"最终info结果是:$it" // 是根据匿名函数最后一行的变化而变化}} ?: "info你原来是null,请检查代码..."}
}// TODO 71.Kotlin语言的 计算属性 与 防范竞态条件
fun main() {// 背后隐式代码:System.out.println(new testclass().getNumber());println(testclass().number)// 背后隐式代码:new testclass().setNumber(9);// testclass().number = 9 // val 根本就没有 setXXX函数,只有 getXXX函数// 背后隐式代码:System.out.println(new testclass().getNumber2());println(testclass().number2)// 背后隐式代码:System.out.println(new testclass().getShowInfo());println(testclass().getShowInfo())
}
主构造函数
// 主构造函数:规范来说,都是增加_xxx的方式,临时的输入类型,不能直接用,需要接收下来 成为变量才能用
// _name 等等,都是临时的类型,不能直接要弄,需要转化一下才能用
class test(_name: String, _sex: Char, _age: Int, _info: String) // 主构造函数
{var name = _nameget() = field // get不允许私有化private set(value) {field = value}val sex = _sexget() = field// set(value) {} 只读的,不能修改的,不能set函数定义val age: Int = _ageget() = field + 1val info = _infoget() = "【${field}】"fun show() {// println(_name) 临时的输入类型,不能直接用,需要接收下来 成为变量才能用println(name)println(sex)println(age)println(info)}
}fun main() {val p = test(_name = "Zhangsan", _info = "学习KT语言", _age = 88, _sex = 'M')// println(p.name)// p.name = "AAA" 被私有化了,不能调用p.show()
}// 一步到位,不像上面是分开写的
class test (var name: String, val sex: Char, val age: Int, var info: String)
{fun show() {println(name)println(sex)println(age)println(info)}
}// TODO Kotlin语言的主构造函数里定义属性
fun main() {test(name = "Zhangsan", info = "学习KT语言", age = 88, sex = 'M').show()
}
次构造函数
class test(name: String) // 主构造
{// 2个参数的次构造函数,必须要调用主构造函数,否则不通过, 为什么次构造必须调用主构造?答:主构造统一管理 为了更好的初始化设计constructor(name: String, sex: Char) : this(name) {println("2个参数的次构造函数 name:$name, sex:$sex")}// 3个参数的次构造函数,必须要调用主构造函数constructor(name: String, sex: Char, age: Int) : this(name) {println("3个参数的次构造函数 name:$name, sex:$sex, age:$age")}// 4个参数的次构造函数,必须要调用主构造函数constructor(name: String, sex: Char, age: Int, info: String) : this(name,sex) {println("4个参数的次构造函数 name:$name, sex:$sex, age:$age, info:$info")}
}
// name: String, sex: Char, age: Int, info: String
fun main() {val p = KtBase74("李元霸") // 调用主构造test("张三", '男') // 调用 2个参数的次构造函数test("张三2", '男', 88) // 调用 3个参数的次构造函数test("张三3", '男', 78, "还在学校新语言") // 调用 4个参数的次构造函数
}
默认参数
class test(name: String = "李元霸") // 主构造
{init {println(name)}// 2个参数的次构造函数,必须要调用主构造函数constructor(name: String = "李连杰", sex: Char = 'M') : this(name) {println("2个参数的次构造函数 name:$name, sex:$sex")}// 3个参数的次构造函数,必须要调用主构造函数constructor(name: String = "李小龙", sex: Char = 'M', age: Int = 33) : this(name) {println("3个参数的次构造函数 name:$name, sex:$sex, age:$age")}// 4个参数的次构造函数,必须要调用主构造函数constructor(name: String = "李俊", sex: Char = 'W', age: Int = 87, info: String = "还在学校新开发语言") : this(name) {println("4个参数的次构造函数 name:$name, sex:$sex, age:$age, info:$info")}
}fun main() {val p = test("李元霸2") // 调用主构造test("张三", '男') // 调用 2个参数的次构造函数test("张三2", '男', 88) // 调用 3个参数的次构造函数test("张三3", '男', 78, "还在学校新语言") // 调用 4个参数的次构造函数test() // 到底是调用哪一个 构造函数,是次构造 还是 主构造 ? 答:优先调用主构造函数
}
初始化块
/*class A {{}A() {}}*/// username: String, userage: Int, usersex: Char 临时类型,必须要二次转换,才能用
class test (username: String, userage: Int, usersex: Char) // 主构造
{// 这个不是Java的 static{}// 相当于是Java的 {} 构造代码块,对象每次初始化都会被调用// 初始化块 init代码块init {println("主构造函数被调用了 $username, $userage, $usersex")// 如果第一个参数是false,就会调用第二个参数的lambda,并且抛出异常// 判断name是不是空值 isNotBlank ""require(username.isNotBlank()) { "你的username空空如也,异常抛出" }require(userage > 0) { "你的userage年龄不符合,异常抛出" }require( usersex == '男' || usersex == '女') { "你的性别很奇怪了,异常抛出" }}constructor(username: String) : this(username, 87, '男') {println("次构造函数被调用了")}fun show() {// println(username) // 用不了,必须要二次转换,才能用}
}
// 临时类型只有在 init代码块才能调用
fun main() {test("李四", userage = 88, usersex = '女') // 调用主构造println()test("王五") // 调用次构造test("李四", userage = -1, usersex = 'M') // 调用主构造test("李四", userage = 1, usersex = '男') // 调用主构造
}
构造初始化顺序
// 第一步:生成val sex: Char
class test(_name: String, val sex: Char) // 主构造
{// 第二步: 生成val mName // 由于你是写在 init代码块前面,所以先生成你, 其实类成员 和 init代码块 是同时生成val mName = _nameinit {val nameValue = _name // 第三步:生成nameValue细节println("init代码块打印:nameValue:$nameValue")}// 次构造 三个参数的 必须调用主构造constructor(name: String, sex: Char, age: Int) :this(name, sex) {// 第五步:生成次构造的细节println("次构造 三个参数的, name:$name, sex:$sex, age:$age")}// 第四步val derry = "AAA"// 纠正网上优秀博客的错误: 类成员先初始生成 再init代码块初始生成 错误了// init代码块 和 类成员 是同时的,只不过你写在 init代码块前面 就是先生成你
}
fun main() {// 调用次构造test("李元霸", '男', 88) // 调用次构造
}
延迟初始化lateinit
class testClass {// lateinit val AAA; // AAA 无法后面在修改了,我还怎么延时初始化?lateinit var responseResultInfo: String // 我等会儿再来初始化你,我先定义再说,所以没有赋值// 模拟服务器加载fun loadRequest() { // 延时初始化,属于懒加载,用到你在给你加载responseResultInfo = "服务器加载成功,恭喜你"}fun showResponseResult() {// 由于你没有给他初始化,所以只有用到它,就奔溃// if (responseResultInfo == null) println()// println("responseResultInfo:$responseResultInfo")if (::responseResultInfo.isInitialized) {println("responseResultInfo:$responseResultInfo")} else {println("你都没有初始化加载,你是不是忘记加载了")}}
}fun main() {val p = testClass()// 使用他之前,加载一下(用到它才加载,就属于,懒加载)p.loadRequest()// 使用他p.showResponseResult()
}
惰性初始化
class testClass {// >>>>>>>>>>>>>>>>>>> 下面是 不使用惰性初始化 by lazy 普通方式(饿汉式 没有任何懒加载的特点)val databaseData1 = readSQlServerDatabaseAction()//一初始化就会调用方法,并不会等到需要用时才调用// >>>>>>>>>>>>>>>>>>> 使用惰性初始化 by lazy 普通方式val databaseData2 by lazy { readSQlServerDatabaseAction() }private fun readSQlServerDatabaseAction(): String {println("开始读取数据库数据中....")println("加载读取数据库数据中....")println("加载读取数据库数据中....")println("加载读取数据库数据中....")println("加载读取数据库数据中....")println("加载读取数据库数据中....")println("加载读取数据库数据中....")println("加载读取数据库数据中....")println("加载读取数据库数据中....")println("结束读取数据库数据中....")return "database data load success ok."}}// lateinit 是在使用的时候,手动加载的懒加载方式,然后再使用
// 惰性初始化by lazy 是在使用的时候,自动加载的懒加载方式,然后再使用
fun main() {// >>>>>>>>>>>>>>>>>>> 下面是 不使用惰性初始化 by lazy 普通方式(饿汉式 没有任何懒加载的特点)val p = testClass()Thread.sleep(5000)println("即将开始使用")println("最终显示:${p.databaseData1}")// >>>>>>>>>>>>>>>>>>> 使用惰性初始化 by lazy 普通方式
// val p = testClass()
//
// Thread.sleep(5000)
//
// println("即将开始使用")
//
// println("最终显示:${p.databaseData2}")}
Any超类
// 在KT中,所有的类,都隐士继承了 : Any() ,你不写,默认就有
// Any类在KT设计中:只提供标准,你看不到实现,实现在各个平台处理好了
class Obj1 : Any()
class Obj2 : Any()
class Obj3 : Any()
class Obj4 : Any()
class Obj5 : Any()
class Obj6 : Any()
// Any == java Object
fun main() {println(Obj1().toString())
}
继承与open关键字
// KT所有的类和类中的方法,默认是final修饰的,不能被继承,和Java相反
// open:移除final修饰
open class Person(private val name: String) {private fun showName() = "父类 的姓名是【$name】"// KT所有的函数,默认是final修饰的,不能被重写,和Java相反open fun myPrintln() = println(showName())
}class Student(private val subName: String) : Person(subName) {private fun showName() = "子类 的姓名是【${subName}】"//在子类也可以调用name,实际上调用的时getName方法override fun myPrintln() = println(showName())}
fun main() {val person: Person = Student("张三")person.myPrintln()
}
类型转换
import java.io.Fileopen class Person2(private val name: String) {fun showName() = "父类 的姓名是【$name】"// KT所有的函数,默认是final修饰的,不能被重写,和Java相反open fun myPrintln() = println(showName())
}class Student2(private val subName: String) : Person2(subName) {fun showName2() = "子类 的姓名是【${subName}】"override fun myPrintln() = println(showName2())}
fun main() {val p: Person2 = Student2("王五")p.myPrintln()println(p is Person2)println(p is Student2)println(p is File)// is + as = 一般是配合一起使用if (p is Student2) {(p as Student2).myPrintln()}if (p is Person2) {// (p as Person2).myPrintln() // 因为子类重写了父类println((p as Person2).showName())}
}
枚举类
enum class Week {星期一,星期二,星期三,星期四,星期五,星期六,星期日
}
fun main() {println(Week.星期一)println(Week.星期四)// 枚举的值 等价于 枚举本身println(Week.星期二 is Week)
}
enum class Exam {Fraction1, // 分数差Fraction2, // 分数及格Fraction3, // 分数良好Fraction4, // 分数优秀
}class Teacher (private val exam: Exam) {fun show() =when (exam) {Exam.Fraction1 -> "该学生分数很差"Exam.Fraction2 -> "该学生分数及格"Exam.Fraction3 -> "该学生分数良好"Exam.Fraction4 -> "该学生分数优秀"// else -> 由于我们的show函数,是使用枚举类类型来做判断处理的,这个就属于 代数数据类型,就不需要写 else 了// 因为when表达式非常明确了,就只有 四种类型,不会出现 else 其他,所以不需要写}
}
fun main() {println(Teacher(Exam.Fraction1).show())println(Teacher(Exam.Fraction3).show())
}
枚举类中定义函数
// 四肢信息class,我就是为了方便toString打印
data class LimbsInfo (var limbsInfo: String, var length: Int) {fun show() {println("${limbsInfo}的长度是:$length")}
}enum class Limbs(private var limbsInfo: LimbsInfo) {LEFT_HAND(LimbsInfo("左手", 88)), // 左手RIGHT_HAND(LimbsInfo("右手", 88)), // 右手LEFT_FOOT(LimbsInfo("左脚", 140)), // 左脚RIGHT_FOOT(LimbsInfo("右脚", 140)) // 右脚; // 结束枚举值// 1. WEEK 这个时候 再定义单调的 枚举值,就报错了,必须所有枚举值,保持一致的效果// 2. 枚举的 主构造的参数 必须和 枚举(的参数) 保持一致fun show() = "四肢是:${limbsInfo.limbsInfo}的长度是:${limbsInfo.length}"fun updateData(limbsInfo: LimbsInfo) {println("更新前的数据是:${this.limbsInfo}")this.limbsInfo.limbsInfo = limbsInfo.limbsInfothis.limbsInfo.length = limbsInfo.lengthprintln("更新后的数据是:${this.limbsInfo}")}
}
fun main() {// 显示枚举值// 一般不会这样用/*println(Limbs.show())println(Limbs().show())*/// 一般的用法如下:println(Limbs.LEFT_HAND.show())println(Limbs.RIGHT_HAND.show())println(Limbs.LEFT_FOOT.show())println(Limbs.RIGHT_FOOT.show())println()// 更新枚举值Limbs.RIGHT_HAND.updateData(LimbsInfo("右手2", 99))Limbs.LEFT_HAND.updateData(LimbsInfo("左手2", 99))Limbs.LEFT_FOOT.updateData(LimbsInfo("左脚2", 199))Limbs.RIGHT_FOOT.updateData(LimbsInfo("右叫2", 199))
}
数据类
data class LoginRequest(var info: String)
// 条件一:服务器请求回来的响应的 JavaBean LoginResponseBean 基本上可以使用 数据类
// 条件二:数据类至少必须有一个参数的主构造函数
// 条件三:数据类必须有参数, var val 的参数
// 条件四:数据类不能使用 abstract,open,sealed,inner 等等 修饰 (数据类,数据载入的事情 数据存储)
单例类
object KtBase87 {/* object 对象类背后做了什么事情public static final KtBase87 INSTANCE;private KtBase87() {} // 主构造废除一样的效果public final void show() {String var1 = "我是show函数...";...System.out.println(var1);}// 这个区域是 object 不同点:static {KtBase87 var0 = new KtBase87();INSTANCE = var0;String var1 = "KtBase91 init...";...System.out.println(var0);}*/init {println("KtBase91 init...")}fun show() = println("我是show函数...")
}fun main() {// object KtBase87 既是单例的实例,也是类名// 小结:既然是 单例的实例,又是类名,只有一个创建,这就是典型的单例println(KtBase87) // 背后代码:println(KtBase87.INSTANCE)println(KtBase87) // 背后代码:println(KtBase87.INSTANCE)println(KtBase87)println(KtBase87)println(KtBase87)println(KtBase87)// 背后代码:KtBase87.INSTANCE.show();println(KtBase87.show())
}
伴生对象
class KtBase89 {// 伴生对象companion object {val info = "DerryINfo"fun showInfo() = println("显示:$info")val name = "Derry"}/* companion object {} 背后的逻辑private static final String name = "Derry";private static final String info = "DerryINfo";public static final KtBase89.Companion Companion = new KtBase89.Companion(xxx);public static final class Companion {@NotNullpublic final String getInfo() {return KtBase89.info;}@NotNullpublic final String getName() {return KtBase89.name;}public final void showInfo() {String var1 = "显示:" + ((KtBase89.Companion)this).getInfo();boolean var2 = false;System.out.println(var1);}private Companion() {}// $FF: synthetic methodpublic Companion(DefaultConstructorMarker $constructor_marker) {this();}}*/
}// 伴生对象的由来: 在KT中是没有Java的这种static静态,伴生很大程度上和Java的这种static静态 差不多的
// 无论 KtBase89() 构建对象多少次,我们的伴生对象,只有一次加载
// 无论 KtBase89.showInfo() 调用多少次,我们的伴生对象,只有一次加载
// 伴生对象只会初始化一次
fun main() {// 背后代码:System.out.println(KtBase89.Companion.getInfo())println(KtBase89.info)// 背后代码:System.out.println(KtBase89.Companion.getName())println(KtBase89.name)// 背后代码:KtBase89.Companion.showInfo()KtBase89.showInfo()// new KtBase89();KtBase89()KtBase89()KtBase89()KtBase89()// ...
}
内部类与嵌套类
// TODO 内部类
// 内部类的特点: 内部的类 能访问 外部的类
// 外部的类 能访问 内部的类
class Body(_bodyInfo: String) { // 身体类val bodyInfo = _bodyInfofun show() {Heart().run()}// 默认情况下:内部的类 不能访问 外部的类,要增加修饰符inner 成为内部类才可以访问外部类inner class Heart { // 心脏类fun run() = println("心脏访问身体信息:$bodyInfo")}inner class Kidney { // 肾脏fun work() = println("肾脏访问身体信息:$bodyInfo")}inner class Hand { // 手inner class LeftHand { // 左手fun run() = println("左手访问身体信息:$bodyInfo")}inner class RightHand { // 右手fun run() = println("右手访问身体信息:$bodyInfo")}}
}// TODO 嵌套类
// 默认情况下:就是嵌套类关系
// 嵌套类特点:外部的类 能访问 内部的嵌套类
// 内部的类 不能访问 外部类的成员
class Outer {val info: String = "OK"fun show() {Nested().output()}class Nested {fun output() = println("嵌套类")}
}fun main() {// 内部类:Body("isOK").Heart().run()Body("isOK").Hand().LeftHand().run()Body("isOK").Hand().RightHand().run()// 嵌套类:Outer.Nested().output()}
copy函数
data class KtBase92 (var name: String, var age: Int) // 主构造
{var coreInfo : String = ""init {println("主构造被调用了")}// 次构造constructor(name: String) : this(name, 99) {println("次构造被调用")coreInfo = "增加非常核心的内容信息"}override fun toString(): String {return "toString name:$name, age:$age, coreInfo:$coreInfo"}
}/* 生成的toString 为什么只有两个参数?答:默认生成的toString 或者 hashCode equals 等等... 主管主构造,不管次构造public String toString() {return "KtBase92(name=" + this.name + ", age=" + this.age + ")";}*/
fun main() {val p1 = KtBase92("李元霸") // 调用次构造初始化对象println(p1)val newP2 = p1.copy("李连杰", 78)println(newP2)// copy toString hashCode equals 等等... 主管主构造,不管次构造// 注意事项:使用copy的时候,由于内部代码只处理主构造,所以必须考虑次构造的内容
}
解构声明
// 普通类
class Student1(var name: String , var age: Int, var sex: Char) {//普通类默认是没有解构声明的,需要自己实现
// // 注意事项:component0不可以 顺序必须是 component1 component2 component3 和成员一一对应,顺序下来的operator fun component1() = nameoperator fun component2() = ageoperator fun component3() = sex
}// 数据类
data class Student2Data(var name: String , var age: Int, var sex: Char)// TODO 93.Kotlin语言的解构声明学习
fun main() {val(name, age, sex) = Student1("李四", 89, '男')println("普通类 结构后:name:$name, age:$age, sex:$sex")val(name1, age1, sex1) = Student2Data("李四", 89, '男')println("数据类 结构后:name:$name1, age:$age1, sex:$sex1")val(_, age2, _) = Student1("李四", 89, '男')println("数据类 结构后: age2:$age2")
}
运算符重载
class AddClass(number1: Int, number2: Int)// 写一个数据类,就是为了,toString 打印方便而已哦
data class AddClass2(var number1: Int, var number2: Int) {operator fun plus(p1: AddClass2) : Int {return (number1 + p1.number1) + (number2 + p1.number2)}// 查看 整个KT可以用的 运算符重载 方式// operator fun AddClass2.
}// TODO 94-Kotlin语言的运算符重载学习
fun main() {// C++语言 +运算符重载就行了 -运算符重载就行了// KT语言 plus代表+运算符重载println(AddClass2(1, 1) + AddClass2(2, 2))
}
数据类
// 普通类
class ResponseResultBean1(var msg: String, var code: Int, var data: String) : Any()
// 转换成java时,只有set get 构造函数// 数据类 -- 一般是用于 JavaBean的形式下,用数据类
data class ResponseResultBean2(var msg: String, var code: Int, var data: String) : Any()
// 转换成java时,会生成set get 构造函数 解构操作 copy toString hashCode equals 数据类 生成 更丰富
Kotlin基础知识5相关推荐
- 第一章 kotlin基础知识
第一章 kotlin基础知识 文章目录 第一章 kotlin基础知识 前言 一.kotlin是什么? 二.kotlin基础知识 1.变量的声明 2.函数定义的几种方式 3.字符串与数字的转换 4.数组 ...
- Kotlin学习(一):Kotlin基础知识
Kotlin学习(一):Kotlin基础知识 定义变量常量 在Kotlin中,定义变量时有以下几点与java不同: 位置不同:在 Kotlin 中,数据类型要放到变量后面,并且用冒号(:)分隔,这正好 ...
- 如何学习kotlin?Kotlin基础知识快速入门
一 概述 Android 1.5系统中Google 引入了NDK功能,支持使用C和C++语言来进行一些本地化开发. 17年官宣kotlin为安卓一级开发语言:所以对于安卓开发者,学习kotlin是必须 ...
- Kotlin基础知识
1. 改进点/基础 //安全判空 val length = text?.length;//类型转换 if (object is Car) {var car = object as Ca }//操作符变 ...
- 【Kotlin学习】Kotlin基础知识
函数与变量 函数 一个普通的函数基本结构 语句和表达式 在kotlin中,if是表达式而不是语句. 语句和表达式的区别 表达式有值,并且能作为另一个表达式的一部分使用 而语句总是包围着它的代码块中的顶 ...
- Android kotlin 基础知识codelab Fragment Summary
创建 fragment 在此 Codelab 中,您向 AndroidTrivia 应用添加了一个 fragment,在本课的后续两个 Codelab 中您将继续在此应用中执行操作. fragment ...
- Kotlin 学习笔记(四)—— 协程的基础知识,面试官的最爱了~
又是一个月没见了,坚持永远是世上最难的事情,但,往往难事才会有更大的收获.与君共勉~ 前段时间一直在学习 Compose,所以导致 Kotlin 笔记系列搁置了好久.一方面是因为 Compose 的学 ...
- Kotlin搞起来——2.基础知识
在上一节中简单的给大家介绍了下Kotlin的特点,以及结合自己实际项目 中的使用来帮助大家了解这门语言,其实真的没你想象中的那么难,本文打算 介绍的是Kotlin中基础相关的一些语法(用法),有个大概 ...
- Kotlin Flow响应式编程,基础知识入门
Kotlin在推出多年之后已经变得非常普及了.相信现在至少有80%的Android项目已经在使用Kotlin开发,或者有部分功能使用Kotlin开发. 关于Kotlin方面的知识,我其实分享的文章并不 ...
- Android技能树 — 树基础知识小结(一),kotlin开源项目
根据上面的基础知识我画了一个归总的图(这样我就不需要写文字介绍了,啊哈哈): [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zd87TfMP-1637304075403 ...
最新文章
- SourceTree中拉取GitLab代码时提示:Too many authentication failures“ fatal: Could not read from remote reposit
- 运营,如何用数据说话?(以电商活动复盘为例)
- SQL Server表分区【转】
- 本地仓库settings.xml中使用阿里的仓库
- ORACLE10G导入11G导出的文件
- jquery 中多条件选择器,相对选择器,层次选择器的区别
- 魅族16s安兔兔跑分揭晓:在优化中不断提高
- UESTC 31 饭卡 card
- Visual Studio开发工具(5):VS2010 精美壁纸,总有一款适合你!
- L1-006. 连续因子-PAT团体程序设计天梯赛
- 静电场求电场强度E和电势U的方法
- CentOS7 安装RabbitMQ 亲测(编写中,有大神请帮忙指点下文中遇到的问题,谢谢)...
- 老版本iOS simulator链接
- 闲鱼如何高效打造一个多业务、低侵入的搜索链路
- 自然语言处理(1)——绪论与概述
- HTTP状态码完整介绍
- linux 批量ping检测
- PS For Mac 内含破解文件下载地址
- 蒙特卡洛树搜索 棋_蒙特卡罗树搜索赢得黑白棋
- BEA-141281
热门文章
- 共享经济新模式——共享员工
- android开发笔记之materialish-progress
- html修改progress背景色,html5 progress标签如何更改进度条颜色?progress进度条详解...
- [CVPR2022] A Dual Weighting Label Assignment Scheme for Object Detection
- 音乐计算机在哪里买,[计算器自带音乐在哪里]语音计算器上的音乐有什
- c# formApp的web browser的兼容性设置
- blender测量3d模型的尺寸
- 电石炉技术的发展及电石炉尾气解决方案
- mysql 默认my.cnf_在mysql中更改默认的my.cnf路径
- mysql 1114错误_mysql出现错误编码1114的解决方法