定义类与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相关推荐

  1. 第一章 kotlin基础知识

    第一章 kotlin基础知识 文章目录 第一章 kotlin基础知识 前言 一.kotlin是什么? 二.kotlin基础知识 1.变量的声明 2.函数定义的几种方式 3.字符串与数字的转换 4.数组 ...

  2. Kotlin学习(一):Kotlin基础知识

    Kotlin学习(一):Kotlin基础知识 定义变量常量 在Kotlin中,定义变量时有以下几点与java不同: 位置不同:在 Kotlin 中,数据类型要放到变量后面,并且用冒号(:)分隔,这正好 ...

  3. 如何学习kotlin?Kotlin基础知识快速入门

    一 概述 Android 1.5系统中Google 引入了NDK功能,支持使用C和C++语言来进行一些本地化开发. 17年官宣kotlin为安卓一级开发语言:所以对于安卓开发者,学习kotlin是必须 ...

  4. Kotlin基础知识

    1. 改进点/基础 //安全判空 val length = text?.length;//类型转换 if (object is Car) {var car = object as Ca }//操作符变 ...

  5. 【Kotlin学习】Kotlin基础知识

    函数与变量 函数 一个普通的函数基本结构 语句和表达式 在kotlin中,if是表达式而不是语句. 语句和表达式的区别 表达式有值,并且能作为另一个表达式的一部分使用 而语句总是包围着它的代码块中的顶 ...

  6. Android kotlin 基础知识codelab Fragment Summary

    创建 fragment 在此 Codelab 中,您向 AndroidTrivia 应用添加了一个 fragment,在本课的后续两个 Codelab 中您将继续在此应用中执行操作. fragment ...

  7. Kotlin 学习笔记(四)—— 协程的基础知识,面试官的最爱了~

    又是一个月没见了,坚持永远是世上最难的事情,但,往往难事才会有更大的收获.与君共勉~ 前段时间一直在学习 Compose,所以导致 Kotlin 笔记系列搁置了好久.一方面是因为 Compose 的学 ...

  8. Kotlin搞起来——2.基础知识

    在上一节中简单的给大家介绍了下Kotlin的特点,以及结合自己实际项目 中的使用来帮助大家了解这门语言,其实真的没你想象中的那么难,本文打算 介绍的是Kotlin中基础相关的一些语法(用法),有个大概 ...

  9. Kotlin Flow响应式编程,基础知识入门

    Kotlin在推出多年之后已经变得非常普及了.相信现在至少有80%的Android项目已经在使用Kotlin开发,或者有部分功能使用Kotlin开发. 关于Kotlin方面的知识,我其实分享的文章并不 ...

  10. Android技能树 — 树基础知识小结(一),kotlin开源项目

    根据上面的基础知识我画了一个归总的图(这样我就不需要写文字介绍了,啊哈哈): [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zd87TfMP-1637304075403 ...

最新文章

  1. SourceTree中拉取GitLab代码时提示:Too many authentication failures“ fatal: Could not read from remote reposit
  2. 运营,如何用数据说话?(以电商活动复盘为例)
  3. SQL Server表分区【转】
  4. 本地仓库settings.xml中使用阿里的仓库
  5. ORACLE10G导入11G导出的文件
  6. jquery 中多条件选择器,相对选择器,层次选择器的区别
  7. 魅族16s安兔兔跑分揭晓:在优化中不断提高
  8. UESTC 31 饭卡 card
  9. Visual Studio开发工具(5):VS2010 精美壁纸,总有一款适合你!
  10. L1-006. 连续因子-PAT团体程序设计天梯赛
  11. 静电场求电场强度E和电势U的方法
  12. CentOS7 安装RabbitMQ 亲测(编写中,有大神请帮忙指点下文中遇到的问题,谢谢)...
  13. 老版本iOS simulator链接
  14. 闲鱼如何高效打造一个多业务、低侵入的搜索链路
  15. 自然语言处理(1)——绪论与概述
  16. HTTP状态码完整介绍
  17. linux 批量ping检测
  18. PS For Mac 内含破解文件下载地址
  19. 蒙特卡洛树搜索 棋_蒙特卡罗树搜索赢得黑白棋
  20. BEA-141281

热门文章

  1. 共享经济新模式——共享员工
  2. android开发笔记之materialish-progress
  3. html修改progress背景色,html5 progress标签如何更改进度条颜色?progress进度条详解...
  4. [CVPR2022] A Dual Weighting Label Assignment Scheme for Object Detection
  5. 音乐计算机在哪里买,[计算器自带音乐在哪里]语音计算器上的音乐有什
  6. c# formApp的web browser的兼容性设置
  7. blender测量3d模型的尺寸
  8. 电石炉技术的发展及电石炉尾气解决方案
  9. mysql 默认my.cnf_在mysql中更改默认的my.cnf路径
  10. mysql 1114错误_mysql出现错误编码1114的解决方法