kotlin(DSL)
领域特定语言和通用编程语言通用编程语言:有一系列足够完善的能力解决几乎所有计算机能解决的问题。领域特定语言(DSL):专注在特定任务上,放弃与之无关的功能。如SQL,正则表达式。他们趋向于解决特定的问题,但对于整个应用程序,他们是无法构造的。 DSL趋向于声明式,而通用编程语言趋向于命令式。他们的区别在于:声明式语言会将想要的结果和执行细节留给解释他的引擎。通常只需要优化一次。而命令式语言要求每一个操作都被独立优化。通常声明式会更有效率一些。而这就带来了一些缺点,比如SQL不能直接嵌入到其他语言中一起使用。单独的语言也需要单独的学习。 DSL风格的API和普通APIDSL的API往往会更加整洁而且通过DSL比单独构造出来的API更具表现力和更适宜工作。 内部DSL通过使用主要语言的特定方式,同时保留独立语法的DSL的主要优点。 DSL的结构通常DSL和API没有明确定义的边界。判断的标准往往是,DSL有着特有的结构或者说文法。一般的API相互调用直接也没有维护上下文。调用时也没有特定语法结构:这种一般被称为命令查询API。与之不同的,DSL的方式会存在一个结构。在kotlin...
kotlin(注解和反射)
注解使用注解使用注解只需要把@符作为名字的前缀,并放在需要注解的代码元素前面。 @Test是一个好用的注解,他可以用来测试一个方法的执行。 @Deprecated这个注解的作用是,声明那些方法已经被弃用,淘汰了。它可以与IDE一起使用。在kotlin中,他还使用了replaceWith参数加强了他。可以提供一个替代者,并且转移参数。(一条不推荐使用的消息,和一个替代者的模式) 注解能够拥有的参数基本数据类型,字符串,枚举,类引用,其他注解。他与java的不同: 要把一个类指定为注解实参,必须在类后面加上::class,表示这个类的反射。 要把另一个注解添加为实参,必须强调注解前的@。 要把一个数组指定为实参,必须使用arrayOf函数 注解使用的参数必须是已知的。也就是常数 注解目标因为一个kotlin的声明往往对应着java的多个声明。如一个属性,java中只会是一个普通的字段。而kotlin中还包括set,get方法和一些隐藏的参数。所以使用点目标可以具体确定是那个代码接受注解。Kotlin 支持的使用点目标的完整列表如下• property一 Java...
kotlin(泛型)
泛型 泛型允许你定义带类型形参的类型。 但是当这个类型的实例被创建出来时,类型形参将会被替换为类型实参的具体类型。即T,E这样的类型形参会被替换为具体的String,Int之类的。 此外,kotlin的编译器可以根据你给定的类型自动推导出所需的类型实参。但是如果你没有给定相关的类型,即编译器无法判断。如你只给定了一个空数组。此时你必须显式的说明你的类型实参是什么(就是必须写清楚<>中的参数类型) 注意,因为java中,泛型是在1.6后的版本才被引入。所以为了和老版的java兼容,他允许使用没有类型参数的泛型类型–所谓的原生态类型。而kotlin不然,他必须声明泛型的类型。 泛型类型和属性如图所示,你必须可以接受一个类型实参进入,用来代替T。 1234fun <T> testFanxing(x: T): T { println( x.hashCode()) return x as T} 他不仅可以适用与函数,也可以适用于属性 12val <T> List<T>.lastIndex:T ...
kotlin(内联函数)(高阶函数控制)
内联函数首先,一般情况下。lambda 表达式会被正常地编译成匿名类。这表示每调用一次lambda 表达式,一个额外的类就会被创建。并且如果 lambda 捕捉了某个变量,那么每次调用的时候都会创建一个新的对象 这会带来运行时的额外开销,导致使lambda...
koltin(高阶函数)
高阶函数定义高阶函数就是以另一个函数为参数,或者返回值为函数的函数。例如常用的filter,map,with等都是高阶函数 函数类型 函数类型必须显示的表示出来,如Unit在普通函数中可以隐藏。但是在函数类型的声明中,必须完整的写出来。 当你已经声明了函数类型后,你再写lambda函数,就可以省略掉lambda函数里的参数类型,而直接写他的参数名。 同样的,函数类型也有可空的。但是有两点区分 123456val testNull1: (Int) -> Int? = { null }val testNull2: ((Int) -> Int)? = nullval testError: (Int) -> Nothing = { throw...
kotlin(运算符重载和其他约定)
在java中,有一些特定的类与语言特性相关联,例如使用了iterable接口的对象可以在for循环中使用。 而在kotlin中,也有很多与语言特性相关的函数命名,对,他与java并不一样,他是选择了将功能和函数命名来绑定。例如,如果在你的类中定义了一个名为 plus 的特殊方法,那么按照约定,就可以在该类的实例上使用+运算符。因此,在 Kotlin 中,我们把这种技术称为约定 约定因为他并不是强依赖于类和他的继承关系。在kotlin中使用约定可以在类中重载其方法,也可以通过扩展函数去添加约定,从而适应现有的java类而不用修改其代码。 运算符重载运算符重载所需要的关键词是operator,而且他所重载的方法都有特定的命名,都必须带上operator关键字。这些表达式同样也满足+-/的基本运算规则。* 表达式 函数名 a * b times a + b plus a - b minus a / b div a % b mod a * = b timesAssign a + =...
使用socket实现一个小型的聊天程序
最近在学习使用kotlin,然后试了试用socket实现一个聊天通信功能。然后发现其实kotlin用的很多库都是JAVA中已经存在的。所以更好的使用kotlin不仅要明白kotlin相对于java的优秀特性和他的跨平台能力,还需要对java也有深度的理解。 使用的插件和包:在build.gradle.kts配置文件中配置你所需要的插件和依赖。 插件 12345678910111213141516plugins { ··· id("com.github.johnrengelman.shadow") version "8.1.1" ···}tasks.withType<ShadowJar> { archiveBaseName.set("myapp") // jar 文件的基本名字 archiveVersion.set("1.0.0") // jar 文件的版本号 archiveClassifier.set("") // jar...
通过文件读写实现聊天对话(kotlin)
首先声明,这个任务并没有实现,我暂时没找到可以用来解决kotlin中实时监听键盘动作,并且不会阻塞的回调方法。 123456789101112131415161718import kotlinx.coroutines.*import java.io.Fileimport java.io.FileReader fun main()= runBlocking{ val file = File("src/main/resources/a.txt") var i = 0 while (true){ println("第${i++}次访问文件") delay(2000) println(file.readText()) println("读取完成")// if(readln()=="chat"){// var message = readln()//...
kotlin(集合和数组)
持有可空类型元素和持有非空类型元素的集合变量自己类型的可空性和用作类型参数 类型...
Kotlin(基本数据类型)
基本数据类型相比于java而言,kotlin不会区分基本数据类型和他们的包装类,都是统一的数据类型,但是他们的底层实现会和java相关。 java中Int,Boolean之类的基本数据类型都和引用类做了区分,基本数组存值,而包装类存储包含该对象的内存地址的引用。 kotlin中他不区分,都是用一个类Int,Boolean等。这样就很方便我们的操作。但是这并不意味着kotlin直接把所有的类都直接写出引用类型了。因为那样的话,就会非常低效。在运行时,数字类型尽可能的使用最高效的方式存储,大部分情况下—-对于变量,属性,参数和返回类型,kotlin的int类型都会编译为java中的基本数据类型。唯一不可行的就是泛型类,集合。他一定会编译为包装类。 可空数据类型...