20天打卡计划 day01
2010年,创造了pycharm和IDEA的大名鼎鼎的语言构建开发工具的JetBrains产生了改良Java这门主流编程语言的想法,设计之初的第一个问题就是兼容数百万行的Java代码库,这个背景也决定了Kotlin的核心目标——为Java程序员提供一门更好的编程语言(better Java—更好的Java)。Kotlin一直在兼容Java语言,这比其他运行在jvm上的语言走得更远,尤其从命名来看,Kotlin也在严格遵循Java的传统。(Java的名字来自印尼爪洼岛的英文,而kotlin是俄罗斯圣彼得堡附近的一座岛屿)
一些改良:
// 懒汉式单例
public class Singleton {
// 指向自己实例的私有静态引用
//保证每次实例化对象拿到的都是这个类
private static Singleton singleton;
// 私有的构造方法
private Singleton(){}
// 以自己实例为返回值的静态的公有方法,静态工厂方法
public static Singleton getSingleton(){
// 被动创建,在真正需要使用时才去创建
if (singleton == null) {
singleton = new Singleton2();
}
return singleton;
}
}
引入了一些Java中没有的特殊类,Data Classes(数据类) ps:在java中我们创建一个数据类POJO需要大量的代码来实现get和set方法,心累。
其他的俺也没学到,之后再说、、
val a : String = "hello world";
与Java相反,kotlin的类型名放在变量名的后面,为什么采用这种风格,我们来对比一下Java
String a = "hello world";
与Java对比,第一是变量类型的位置,kotlin支持省略类型的声明,也就是可以写成下面这样,系统会自动推导出变量的类型,Kotlin是静态语言,但是通过增强的类型推导,来改善静态语言需要大量的声明类型这一情况。
val a = "hello world";
var和val:简单来说,val就是加了final修饰的var,引用不可变;
这里我们要了解一下什么叫做函数式语言,在函数式语言中,函数是一等公民,主要成分是函数,可以把函数作为参数(接受一个过程(函数)为参数),结果也可以是函数(返回一个过程),这样的函数叫做高阶函数,高阶函数是一种更加高级的抽象形式,极大得增强了语言得表达能力。
Kotlin不是函数式语言,但是它天然支持部分函数特性(java8新特性也已经支持部分函数式特性):
fun foo(x:Int){
//函数中定义函数
fun double(y:Int) : Int{
return y * 2
}
println(double(x))
}
举个栗子说一说函数式的牛逼之处:
假设我们要做一个统计用户信息的应用,刚开始我们的信息只有很少一部分,直接匹配名字就可以得到:
data class User(
val name : String,
val id : Int,
val gender : String,
val age : Int)
class App{
fun findUser(users : List<User>): List<User>{
val res = mutableListOf<User>()
for (user in users){
if(user.name == "汪涵"){
res.add(user)
}
}
return res;
}
}
后来我们要叫汪涵的人多了,这个时候我们可以通过在if语句中加限定条件,比如年龄性别等,慢慢越加越多,代码的业务逻辑耦合也越来越高,怎么解决这个办法呢?
把所有的逻辑筛选 -行为- 抽象成一个 -参数- 传入findUser中
class test{
fun isUser(user : User) : Boolean{
return user.name == "汪涵" && user.gender == "男" && user.id == 1;
}
}
函数我们有了,现在解决第二个问题怎么把函数作为参数,也就是怎么传,传什么的问题:
1.解决函数传递的类型问题(传什么):
函数作为参数传递,也需要具备具体的参数信息。
在Kotlin中函数类型(函数作为参数传递的类型,类似整型作为形参的int)的格式为:
(Int) -> Unit //Unit目前当作void,但是作为返回类型必须显式声明
/**
* 通过->来传递参数,左边是参数类型,右边是返回值类型
* 必须用一个括号来包裹参数类型
* 返回值类型即使是Unit,也必须显示声明
* 空值传参:() -> Unit
* 多值传参:(String, Int) -> Unit
* 为声明参数指定名字:(name: String, id: Int) -> Unit
* 若某些情况id可空:(name: String, id: Int?) -> Unit
* 若函数类型的变量可选:((name: String, id: Int?) -> Unit)?
* 高阶函数还支持返回另外一个函数:
* 对比 (Int) -> ((Int) -> Unit)
* (Int) -> Int -> Unit
* ((Int) -> Int) -> Uint
*/
明确了这些之后,传它!
class App{
fun findUser(users : List<User>,
testone : (User) -> Boolean
): List<User>{
val res = mutableListOf<User>()
for (user in users){
if(testone(user)){
res.add(user)
}
}
return res;
}
}
2.解决函数传递怎么传的问题
直接上代码吧:
App.findUser(Users,test :: isUser)
在c++中有命名空间的概念,使用::来调用某个类下的方法来获得方法或成员的引用,Kotlin中也可以用::来拿到类的属性或方法的引用。
和.的不同是,获取引用而不是调用(拿到但不用)。
今天结束啦啦啦啦,明天学习高阶函数的结尾和Lambda