Kotlin开发Android《第一行代码》

  • Kotlin简单语法
    • 变量
      • 1. 关键字var和val
      • 2.不必显式声明变量类型
      • 3. 变量的类型
    • 函数
      • 函数的定义
      • 语法糖
    • 流程控制
      • 条件控制
        • if
        • when
      • 循环
        • while
        • for- in
    • Kotlin 面向对象的编程语言
      • 类与对象
        • 普通类
        • 类的继承
        • 构造函数
          • 主构造函数
          • 次级构造函数
        • 接口
        • 可见性
        • 数据类
        • 单例类
    • Lambda表达式
    • JAVA函数式API
    • 空指针
      • ?
      • ?.
      • ?:
      • !!
      • let
    • 字符串内嵌表达式
    • 函数设置参数默认值
    • 延迟初始化
    • 密封类

看书总是觉得都懂了,实际操作二百五,试着默写出来才是真的懂,就是写写有点累。
主要是看(郭霖的《第一行代码》第三版)

Kotlin简单语法

变量

1. 关键字var和val

1.var 和val的区别
var:可以改变的变量
val :第一次赋值后,无法进行更改的变量
注意:当变量赋值的时候,首先选择val进行,如果val不满足要求的情况下才选择var,这样能够使得代码更加健壮。

var a=10
a=20  //正确 变量可变所以可以
val b=20
b=20 //错误 不可变的变量 再次进行赋值操作 

2.不必显式声明变量类型

kotlin 具备强大的推导能力,所以变量的定义的时候无需显示声明。
但是延迟赋值的时候,就需要显示声明了,声明的方法是 变量名后面:加类型
延迟赋值:通常使用了lateinit ,在对象的属性声明的时候不初始化,在用到的时候再初始化。

val a=10 //kotlin 推导得出a是Int类型
val b:Int =10;//显式声明Int类型,并赋值10,这时候不需要进行推导了,但是这里的显式申明可要可不要

3. 变量的类型

如上面例子所示,和java相比,Int 是大写的,这代表Kotlin放弃了基础数据类型,全部选择的是对象数据类型。Int,Long,Short,Float,Double,Boolean,Byte,Char

函数

函数的定义

函数的定义fun关键字+函数名+(参数:变量类型)+:返回值类型+函数体。无返回值时不需要声明返回值类型。

//无返回值
fun saySomething(msg:String){ print(msg)
}
//多参数
fun saySomething(msg:String,name:String){ print(name+"说"+msg)
}//有返回值
fun saySomething(msg:String):Int{ print(msg)return 1
}

语法糖

当函数只有一条语句的时候,直接写在函数的后面用等号连接

//语法糖版本
fun saySomething(msg:String)= print(msg)

流程控制

条件控制

if

if 语句和大多数的语言里面的if语句相类似,唯一新增了一个就是可以有返回值,返回值是每个条件里面的最后一行

//传统写法
fun largerNumber(num1:Int,num2:Int):Int{var max=0;if (num1>num2){max= num1 } else{max=num2}return max
}//新特性的改写
fun largerNumber(num1:Int,num2:Int):Int{if (num1>num2){num1 } else{num2}
}//语法糖  因为只有一句语句( if和else是整体,结果就是返回一个值) ,套用上面的语法糖所以可以用等号连接
fun largerNumber(num1:Int,num2:Int):Int= if (num1>num2) num1 else num2//当然既然采用了语法糖用等于号连接,那么也可以省略显式声明,让kotlin自己推导类型
fun largerNumber(num1:Int,num2:Int)= if (num1>num2) num1 else num2

when

类似于switch,但是强于switch,变量不只局限于整形或者是字符串。而且不需要break语句。 【匹配值】->{执行逻辑},当执行逻辑只有一行代码,{}可以省略不写。而且when和if一样也是可以有返回值的,

//传统写法
fun getScore(name:String):Int {var score =0when(name){"Tom"->{ score =66 }  //不省略{}写法"ANN"-> score =90 //省略写法else -> score =0}return score
}//语法糖写法 when整体是一个语句
fun getScore(name:String)= when(name){"Tom"->66"ANN"-> 90else -> 0
}//不带参数的when写法
fun getScore(name:String)= when(){name=="Tom"->66 // 前面写匹配的条件 name== "ANN"-> 90else -> 0
}

when 还支持类型的匹配,其中关键字is.
Number 是抽象类,Int之类和数字相关的类都是它的字类

fun checkNumber(num:Number){when(num){is Int -> println(" is Int")is Double -> println(" is Double ")else -> println(" other Type ")}
}

循环

while

这个写法和java中一样的,或者是C啥的,只要有基础的都知道,所以直接来个例子吧

fun main(){var i=1;while(i<10)  {print("第"+i+"次")i=i+1}}

do-while 和while的区别。
do-while语句不管条件是否满足,肯定执行一次。而while是只有条件满足才会进入。

fun main(){var i=10;do {print("当前i="+i)}while (i<9)
}

for- in

和java中常用的for-i循环不同,kotlin舍弃了这个循环,增强了for-each循环这个模式,也就是现在的for-in循环,能够满足大多数的场景,如果遇到不满足的场景可以选择while语句进行实现。

fun main(){for ( i in 1..10){//..为关键字,1..10 代表创建了 [1,10]闭区间的,并且默认步长为1,可以省略,也就是i的递增顺序是 i=i+1println("当前"+i)}}//写完整
fun main(){for ( i in 1..10 step 1){  // step 关键字,步长。当然可以设置其他的数字,用来跳过某些值println("当前"+i)}}// 当遇到长度为10的数组,其实下标是[0,10) 也就是左闭右开,用until
fun main(){for ( i in 0 until 10 ){ //同样省略步长 默认为1,用until关键字就是创建了 [0,10)区间println("当前"+i)}}//刚刚的例子是递增,那么有时候要递减 downTo
fun main(){for ( i in 10 downTo 0 ){ //downTo ,创建了两端闭合降序的[10,0]区间println("当前"+i)}}

Kotlin 面向对象的编程语言

类与对象

普通类

class 关键字,和java一样的,唯一的不同的,当实例化的时候,不需要new关键字,调用 val person =Person(); 用val是因为,我们首选应当是val,当val不满足才选用var

 class Person {var name="" ;var age =0 ;
}

类的继承

和java不同,java里面的类默认是可以继承的,但是kotlin里面,只有写有关键字open的类能继承,当然抽象类肯定是可以继承。
改写Peson类

open class Person {var name="" ;var age =0 ;
}

然后创建Student 类去继承

class Student :Person(){var sno=""var grade=0}

这时候会发现:是继承的关键字,但是为什么是Person(),咋比java多了个()呢?
这涉及到了主构造函数,和次级构造函数,我们现在记住一个死理
首先一定要知道,当子类去继承父类的时候,子类的构造函数一定要调用父类的构造函数。

构造函数

一个类有两种构造函数,主构造函数,次级构造函数,类会默认带有一个无参的主构造函数。
同时kotlin规定了一个类只能有一个主构造函数,但是能有多个次构造函数
注意点只能有一个主构造函数,代表可以有0个或者1个主构造函数
多个次构造函数,代表可以有0到多个。
(不是说默认带着无参的主构造函数吗?为什么又可以0个,0个就是当你没显式声明主构造函数的参数,但是又定义了次级构造函数。简单而言,相当于默默无闻的主构造函数被高调的次级构造函数,顶替了,只有当高调的主构造函数,才能不被次级构造函数给顶替)。

所以厉害关系排行榜
显式声明的主构造函数>次级构造函数>默认的主构造函数
(默认的主构造函数相较于前两者,更特别一点,它一旦遇到更厉害的角色出现,就被顶替消失了)

主构造函数

每个类默认会带有一个无参数的主构造函数,但是主构造函数也可以显示的声明参数,参数写的位置就在类名的后面。如果显示声明了参数,之后调用的话,就要传入参数了。
主构造函数重要的是,它是没有函数体的。如果想要主构造函数执行某些代码,必须采用init关键字。


open  class Person { //其实自带一个Person()的主构造函数var name="" ;var age =0 ;
}// 显示声明主构造函数的参数
open class (val name:String,val age:Int) {//其实自带一个Person()的主构造函数,你会发现我没有在类里面定义name和age字段了//因为写在主构造函数里面的传入参数,如果前面带有val或者var关键字自动会变成类的字段的}//由于主构造函数没有函数体,那我们想用主构造函数构造的时候还要执行某些语句怎么办
//那么有 init结构体,专门为主构造函数设计的open class Person(val name:String,val age:Int) {init {print("初始化")}
}

那么现在再来看原来的代码下图为例,是不是就好理解很多。

1 Person类里面没有次级构造函数,Person类后面没跟()说明没显示声明主构造函数,所以拥有一个自带无参数的主构造函数。
2. Student 类里面的: 表达了 Student继承了Person类
3. Student 和Person类情况一样,只有默认的主构造函数。
(同时要知道,继承的话子类必须实现父类的构造函数,现在子类只有默认的主构造函数,父类也是默认的主构造函数,所以子类的主构造函数必须实现父类的主构造函数)
4.class Student :Person() 里面的() 代表 Student默认的主构造函数去实现了Person里面的默认的主构造函数。

所以方便记忆的话,可以当类的:后面出现()的时候就代表了是子类的主构造函数,在实现父类的某一个构造函数。那到底是实现的是父类哪一个构造函数呢?就看()里面的参数,和哪个对的上就是哪个。

open  class Person { //其实自带一个Person()的主构造函数var name="" ;var age =0 ;
}class Student :Person(){ //子类一定要调用父类的构造函数,父类的构造函数只有Person()var sno=""var grade=0}

同理当父类显示声明了主构造函数的参数的话呢?

 open class Person(val name:String,val age:Int) {//只有一个主构造函数 Person(name,age)init {print("初始化")}
}//当Person变成上面这样的话,这样固然可以,但是每个人都是一样的名字了
class Student :Person("小小","12"){var sno=""var grade=0
}//较为正确的应该是,构造Student的时候,输入学号,年级,名字和年龄。但是很奇怪的是,为什么name和age这两个字段咋前面没有变量的标识符,val或者var呢?
//因为之前说了如果写在主构造函数里面用val和var,就默认变成这个类的字段,那么Student里面S有name和age字段了,但是Person不是也有age和name吗,会冲突的。
//所以只是让它前面没有标识符,作用域只在主构造函数里面。
class Student(val sno:String,val grade:Double,name:String,age:Int) :Person(name,age){}
次级构造函数

constructor 关键字定义,当既有主构造函数,又有次级构造函数时候。次级构造函数必须直接或者间接的调用主构造函数。
所以在这

次级构造函数 --》 主构造函数 --》父构造函数
(这个调用满足俩要求,次级构造函数必须直接或者间接的调用主构造函数,子构造函数必须实现主的构造函数)
主构造函数 --》父构造函数 (子构造函数必须实现父的构造函数)

class Student(val sno:String,val grade:Double,name:String,age:Int) :Person(name,age){constructor( sno:String,grade:Double,name:String):this(sno,grade,name,0){//构造函数1 ,直接调用主构造函数}constructor( sno:String,name:String):this(sno,2.0,name){//构造函数1 ,间接调用主构造函数}
}

特殊例子,有次级构造函数,但是没显示声明主构造函数,所以只有次级构造函数。没有主自然不调用。
Student 是继承Person 类的,那么子构造函数必须实现父的构造函数,那么自然就是这个次级构造函数,直接去继承父亲的构造函数了。

class Student :Person {var sno="";var grade=0.0;constructor(  //次级构造函数里面不能有var和val,那么自然也无法自动生成字段,那么只能在类里面手动定义了。sno:String,grade:Double,name:String,age:Int):super(name,age){}}

接口

kotlin的接口中支持,对函数的默认实现。

interface Study {fun readBooks()fun doHomeWork(){ //函数的默认实现println("做作业")}}

类对接口的实现也是用:关键字,然后可以发现没有对doHomeWork函数进行实现,因为Study 接口中有默认实现,所以不实现是不会报错的。但是如果readBooks函数没进行重写实现,那么就会报错的,因为接口中这个方法是没有实现的。

Kotlin中使用override关键字来重写父类和实现接口中的函数。

class Student(name:String,age:Int) :Person(name,age),Study{var sno="";var grade=0.0;constructor( ):this("小小",1){}override fun readBooks() {println("读书");}
}

可见性

Kotlin的默认可见性是Public。

//没写可见性open class Person(val name:String,val age:Int) {init {print("初始化")}
}//上面等同,但是多此一举了
public open class Person(val name:String,val age:Int) {init {print("初始化")}
}

数据类

数据类,只要前面写上data关键字,其实Kotlin 默认实现了 equals(),hashCode(),toString()方法

//由于这个类里面没有其他代码的时候,就可以省略掉大括号了
//相信你们应该还记得吧  主构造函数里面出现了var 或者val 代表着这个字段就是这个类的字段(属性)
data class Cellphone(var name:String,var price :Double)

单例类

全局只有最多拥有一个实例的单例类,只需要object关键字就行。

object Singleton {fun doText(){ //里面定义的方法print("测试")}
}

调用单例类的方法很简单,有点像是调用静态方法

Singleton .doText();//但是实际上 kotlin给我们在背后创建了实例,而且全局有且只有一个实例。

Lambda表达式

Lambda是一小段可以作为参数传递的代码片段。什么意思呢,通常写函数的时候,我们定义的参数是Int,String 啊之类的,但是现在写函数的时候我们可以选择传入的参数是一个Lambda的表达式,(也就是一小段代码作为参数)。实不相瞒,个人认为这个东东很像回调函数。

Lambda式子的语法结构,函数体中最后一行代码就是lambda的返回值
{参数名1:参数类型,参数名字:参数类型 -> 函数体}

以一个我写的无病呻吟的一个传入参数是Lambda表达式的函数textLambda为例子。

//参数名为test  然后参数的类型是 一个Lambda表达式
//并且这个Lambda 会有一个String类型的传入参数,和Int类型的返回值
//也就是说 这个函数已经规定了这个Lambda 传入参数是什么类型,返回值是什么类型。
fun textLambda(test:(String) -> Int){val str1="aaa"val num= test(str1)if (num>5) print("短字符串")else print("长字符串")
}

那么调用的时候,我就要传入一个符合这个函数要求的lambda表达式

//调用的时候,str1:String-> 8 就是我写的lambda表达式
//lambda表达式中 有textLambda传给我的str1这个参数,但是我没用到
//结果 输出 短字符串
textLambda ({str1:String-> 8})// 用传给我的字符串的长度作为返回值
//判定结果 长字符串
textLambda ({str1:String-> str1.length})//kotlin规定 当lambda参数是函数的最后一个参数,可以将表达式移到()后面
textLambda (){str1:String-> str1.length}
//当 lambda参数是函数的唯一一个参数的时候,可以省略掉()
textLambda {str1:String-> str1.length}//kotlin的推导机制,可以让我们省略掉lambda参数列表的类型声明
textLambda {str1-> str1.length}
//当只有lambda只有一个参数的时候,参数名称可以不写 直接用it指代
textLambda {it.length}

通过以上的例子就会发现,其实Lambda表达式和Int之类的没什么区别,Int代表的是一个值,但是Lambda代表的是一段代码罢了。对于参数是Lambda表达式的函数而言,它会告诉你它要一个Lambda表达式,然后这个表达式中它会告诉你,它将会给你一个什么类型的参数,然后它需要你返回给它一个什么类型的结果。至于中间的过程它一概不管。

JAVA函数式API

当kotlin调用java代码的时候,也可以使用JAVA函数式API。但是要满足以下条件:**调用的java方法接收一个java单抽象方法的接口参数。**以上的句子很难懂但是没关系,例子来解释,Android的java开发中经常要开线程,Thread方法很熟悉吧,就以他为例子。
解释:

 java代码中,看下定义:Thread 方法,参数是Runnable 类型的参数public Thread(Runnable target) {init(null, target, "Thread-" + nextThreadNum(), 0);}
再看下Runnable 的定义,会发现它是一个接口,并且只有一个抽象方法也就是run方法。
public interface Runnable {public abstract void run();
}
那么Thread方法它就是满足上面那段话的,首先Thread 是一个java方法,并且它接收的参数Runnable是一个接口,然后这个接口里面有一个抽象方法。
所以说当kotlin中调用Thread方法中那个接口参数的单抽象方法可以写成Lambda表达式

实战

//java中调用thread的写法(匿名类的写法)new Thread(new Runnable() {@Overridepublic void run() {System.out.println("线程");}});// 原模原样改造成kotlin的话,没有new关键字,方法的关键字是fun(匿名类的写法采用了object关键字)
Thread(object: Runnable {override fun run() {print("线程");}})
// 但是刚才说了,这个 Thread是满足java函数式api的,也就是说可以简写,因为只有Runnable只有一个待实现方法,所以可以不显示重写run方法
Thread( Runnable {print("线程");})   //  Thread方法里不沉溺在一个以上的java单抽象方法接口参数,可以省略接口名字
Thread( {print("线程");})// lambada表达式是方法的最后一个参数
Thread() {print("线程")}     // lambada表达式只有一个lambada表达式的参数,省略括号Thread{print("线程")}

这里的java函数式API的使用,都是限定于从kotlin中调用java方法,并且单抽象方法也必须用java语言定义的。

空指针

kotlin默认的是变量不为空。

?

fun doStudy(study:Study){ //这里的study参数传空就会报错
}

如果想要空,后面加上一个?,表示可以为空,但是这时候需要自己把空异常都处理掉。

fun doStudy(study:Study?){ //这里的study参数传空就会报错
}

?.

代表当对象为空不做任何事情,当对象不为空调用方法

例如
if(a!=null){
a.doSomething()
}//可以变成a?.doSomething()

?:

val c=a?:b  //意思是当a不为空 返回a,但是当a为空返回b

!!

非空断言,当可为空的全局变量的时候,在不为空的时候才调用某个方法,但是kotlin没办法知道

var content:String?="hello"
fun main(){if(content!=null){doUpperCase()}}
fun doUpperCase(){content.toUpperCase(); //代码会异常
}

采用!!,告诉kotlin 这个我自己确定不为空,有异常的话我来解决。

var content:String?="hello"
fun main(){if(content!=null){doUpperCase()}}
fun doUpperCase(){content!!.toUpperCase();
}

let

一个函数,提供了函数式api接口,并将原始调用对象作为参数传递到lambda表达式里面。它配合?.可以发挥很大作用。而且let可以处理全局变量的判空问题。

a?.doSomething()
a?.doStudy()//上面其实a是否为空每一句都判断了,代码复杂了。但是用let函数,在外面先判断一次,然后就做操作a?.let{
a1-> a.doSomething()
a.doStudy()
}//再次简化,当lambda表达式里面只有一个传入参数的时候,可以声明直接用it来指代
a?.let{
it.doSomething()
it.doStudy()
}

字符串内嵌表达式

在字符串中允许${}的方式来内嵌,可以把一堆+给省略掉了。

   val name="小明"val age="20"println("你好,"+name+",原来你已经"+age+"岁了呀!")println("你好,${name},原来你已经${age}岁了呀!")
-----------------结果--------------------
你好,小明,原来你已经20岁了呀!
你好,小明,原来你已经20岁了呀!

函数设置参数默认值

fun main(){doPrint()doPrint(name = "小花") //键值对的传参方式,可以无视顺序doPrint(age = 10)}
fun doPrint(name:String="小明",age:Int=20){ //设置默认值 println("你好,${name},原来你已经${age}岁了呀!")
}
----------------结果----------------
你好,小明,原来你已经20岁了呀!
你好,小花,原来你已经20岁了呀!
你好,小明,原来你已经10岁了呀!

延迟初始化

使用lateinit关键字,使用了这个关键字之后,我们可以不需要定义的时候就设置默认值,可以后面用到的时候初始化。
这个的作用是可以让我们用到全局变量少很多非空校验,当然这个的前提是你确保用到这个变量的时候已经完成初始化才行。

lateinit var a:String //没有初始值
var b=""   //必须设置初始值

判断是否进行过初始化。 ::a.isInitialized 代表a是否进行过初始化,没有的话进行初始化。

 if(!::a.isInitialized){a=""}

密封类

普通写法,创建一个Result.kt文件,也就是kotlin文件。
interface Result
class Success(val msg:String):Result()
class Failure(val error:Exception):Result()
为了过编译一定要写个else,但是实际结果肯定不会有else。
还有就是当Result又多了一个Unknown类继承它,但是方法里面没有去判断,走到else导致系统抛出异常,程序崩溃。

fun getResultMsg(result:Result)=when(result){
is Success ->result.msg
is Failure->result.error.message
else throw IllegalArgumentException()
}

但是密封类的写法,创建一个Result.kt文件。
sealed class Result
class Success(val msg:String):Result()
class Failure(val error:Exception):Result()
不需要写else,而且如果后续增加了Unknown继承它,kotlin会强制你每个都进行判断,否则编译通不过。密封类是一个可继承的类,所以当其他类继承它的时候要实现它的主构造函数,所以是:Result()

fun getResultMsg(result:Result)=when(result){
is Success ->result.msg
is Failure->result.error.message
}

密封类和子类只能定义在同一个文件的顶层位置,不能嵌套在其他类里面。

Kotlin开发Android相关推荐

  1. 用Kotlin开发android平台语音识别语义理解应用

    用Kotlin开发android平台语音识别,语义理解应用(olamisdk) 转载请注明CSDN博文地址:http://blog.csdn.net/ls0609/article/details/75 ...

  2. 用Kotlin开发android平台语音识别,语义理解应用(olamisdk)

    本文使用Kotlin开发Android平台的一个语音识别方面的应用,用的是欧拉密开放平台olamisdk. 1.Kotlin简介 Kotlin是由JetBrains创建的基于JVM的编程语言,Inte ...

  3. 使用Kotlin开发Android应用 - 环境搭建 (1)

    一. 在Android Studio上安装Kotlin插件 按快捷键Command+, -> 在Preferences界面找到Plugins -> 点击Browse repositorie ...

  4. 使用Kotlin开发Android应用初体验

    使用Kotlin开发Android应用初体验 昨晚,最近一届的谷歌IO大会正式将Kotlin确定为了官方开发语言,作为一名Android开发鸟,怎么能不及时尝尝鲜呢? Kotlin的简要介绍 在开发之 ...

  5. kotlin开发Android入门篇八Kotlin开发Android的基本使用

    基础篇:Kotlin开发Android的基本使用 使用AndroidStudio3.0及以上开发Kotlin在新建项目中勾选这个选项则会默认开发语言为Koltin,然后再gradle(Project的 ...

  6. 用 Kotlin 开发 Android 项目是一种什么样的感受?(二)

    前言 前面我已经写了一篇名为<用 Kotlin 开发 Android 项目是一种什么样的感受?>的文章.文中多数提到的还是 Kotlin 语言本身的特点,而 Kotlin 对于 Andro ...

  7. 使用Kotlin开发Android应用

    作者:snowdream Email:yanghui1986527#gmail.com QQ 群: 529327615 原文地址:https://snowdream.github.io/blog/20 ...

  8. [Android]使用Kotlin开发Android(二)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4829007.html [TOC] 使用Kotlin+OkHtt ...

  9. IDEA基于kotlin开发android程序配置小结

    IDEA功能极其强大,和微软的宇宙第一IDE不相上下.用了很长时间,对它配置的完善性产生了近乎迷信的感情.似乎只要走正常渠道,用它来配置,没有不成功的. IDEA是开发android原生程序的利器,a ...

最新文章

  1. wk一sm5时间温度控制器_新能源汽车电机控制器温度计算及其模型—DC电容篇
  2. 010_jQuery获取和设置内容属性
  3. java 学生成绩排序
  4. 蓝桥杯 - 完美的代价(贪心+模拟)
  5. mockjs中的方法(三)
  6. 爬楼梯(递归——奇数步,偶数步扩展)
  7. Android中的数据库
  8. ci phpexcel mysql_PHPExcel导入数据到mysql数据库
  9. 程序员每天少吃 能活120岁
  10. 程序员为什么要少写代码?
  11. 服务器一直运行python_【已采纳】supervisor在服务器端(linux),如何一直运行你的python代码...
  12. vim 批量替换字符串_Vim 有什么奇技淫巧?
  13. Xamarin.Forms Layout Challenges – Great Places(已全文翻译)
  14. mongodb集群linux日志分割,Linux下Mongodb数据库日志切割及定时删除
  15. 验证GridControl Gridview 单元格。
  16. 在C / C ++中使用INT_MAX和INT_MIN
  17. 七款修复工具介绍:不仅能修复U盘,SD卡、TF卡也能修复!
  18. AdventureWorks2008 数据库安装
  19. python迭代器是什么_python中什么是迭代器
  20. 「BIND9」- DLZ(Dynamically Loadable Zones) @20210212

热门文章

  1. 恒生o32系统介绍_恒生指数日内空间预测模型和实盘对照20201104日
  2. 实在智能RPA亮相2023全球人工智能技术博览会,“能对话的数字员工”引领智能自动化新篇章
  3. ANSYS经典界面中的刚性目标面及其控制节点_51CAE_新浪博客
  4. 【博客134】linux显示磁盘信息—df命令
  5. 2013买房靠不靠谱?---“秒杀”三件最蛋疼的房事儿是关键
  6. 高级软件工程团队第一次作业
  7. selenium3 + python - gird分布式(转载)
  8. 国外问卷调查该怎么做?
  9. ftpd服务器配置文件,中文解释PureFTPd配置文件网络服务器 -电脑资料
  10. 主题单元评价量规用计算机画画,巧用评价量规引领课堂教学