2018-08-24 Kotlin探究之旅-基础篇

每一个进入IT行业的人,想必或多或少都会了解一点关于Oracle和Google的爱恨情仇,关于Java的版权问题,Oracle已经和Google纠缠了多年了,而最近,这场持续了多年的纠纷似乎以Google的败诉而告一段落了!

作为一个Android开发人员,跟着Google混饭吃的我们,应该都很清楚,随着这场官司的败诉,Java随时都有可能从Android主要支持语言的宝座上退下来,届时,作为占领全球百分之七十以上手机系统的Android,必定会选择一门新的语言作为其主要支持语言,无疑,Kotlin的出现,让一切变得没有了争议

在2017年的IO大会上,Google便宣布了,将Android开发的官方语言更换为了Kotlin

那么Kotlin是何许人也,为何能兵不血刃的取代Java这位自Android出生以来便寸步不离的老大哥呢?

下面,便让IT烟酒僧同学给你介绍一下Kotlin这位新同学

Kotlin是由 JetBrains开发的一门同样基于JVM设计的编程语言,自诞生起,便受到了业界各位大神的追捧和赞扬,其中就包含烟酒僧最崇拜的Jake大神

不过,既然能受到如此高的待遇,想必Kotlin也必非浪得虚名,毕竟程序猿是一群非常看重效率的群体,的确,Kotlin也对得起这份待遇,相对Java来说kotlin占据了代码简洁高效、函数式编程、空指针安全、支持lambda表达式、流式API等优势。

而且,Kotlin和Java是互相完美兼容的,两种代码文件可以并存,代码可以互相调用、文件可以互相转换,库文件也可以无障碍地互相调用,据说使用Kotlin基本不会带来额外的成本负担

是不是很 perfect,是不是已经忍不住想认识一下Kotlin了,下面,就让IT烟酒僧同学带你走进kotlin的世界,从基础开始认识kotlin这位It界的新面孔。

数据类型

var 代表变量 可以被修改

变量的声明以及智能类型推断

var i = 10;
i = 19;
//i=99999999999;(超出int的取值范围,报错)
var j = 999999999999999;
var s = "haha"
//显式(指定数据类型)
var i2 : Int =19;
var i3:Byte =127;
//i3=257;(超出byte的取值范围,报错)

val 代表常量,只读,不可以被修改

val a="no"
//a="s" 变量不能被修改

变量的取值范围
kotlin中更常见的容器
Byte 存储值范围 整数 -128--127
Short 存储值范围 整数 -32768--32767
Int 存储值范围 整数 -2147483648--2147483647
Long 存储值范围 整数 -9223372036854775807--9223372036854775807
Float 存储值范围 小数,小数点可以精确到6位
Double 存储值范围 小数 小数点可以精确到15--16位
String 存储值范围 字符串,用""双引号引起来的字符串都可以存

//Byte
val aByte: Byte=Byte.MAX_VALUE
val bByte: Byte=Byte.MIN_VALUE
println("byte的最大值:"+aByte)
println("byte的最小值:"+bByte)
//Long
val along: Long=Long.MAX_VALUE
val blong: Long=Long.MIN_VALUE
println("Long的最大值:"+along)
println("Long的最小值:"+blong)
//二进制
val aInt: Int=0b0011
println("aInt的值"+aInt)

函数入门(偶函数,奇函数.三角函数,幂函数)
计算机的函数就是程序执行的小片段,这些小片段有机的组合在一起就会执行一个业务

//利用函数打印菱形
printlStart()
fun printlStart(){
  println("*")
}
//布尔运算
booleanTest()
fun booleanTest(){
  var num1=4
  var num2=6
  println(num1>num2)//------false
  println(num1<num2)//______true

  //根号5/4/3
  var num3 = Math.sqrt(5.0)-Math.sqrt(4.0)
  var num4 = Math.sqrt(4.0)-Math.sqrt(43.0)
  println(num3>num4)

  //次方(2的100次方)
  var num5 = Math.pow(2.0, 100.0)
  var num6 = Math.pow(3.0, 75.0)
  println(num5>num6)
}

交互式编程
kotlin和java都是基于JVM的
配置环境变量jdk kotlinc
kotlin函数的编写规则
fun 函数名(参数名:参数类型):返回值类型{函数体}
如果返回值类型为Unit 则可以省略

二 字符串(String)/条件控制语句

1 加减乘除

var a = 8
var b = 2
println("a+b==" + plus(a, b))
println("a-b==" + sub(a, b))
println("a*b==" + mutl(a, b))
println("a/b==" + devide(a, b))
//加法运算
fun plus(a: Int, b: Int): Int {
  return a + b
}
//减法运算
fun sub(a: Int, b: Int): Int {
  return a - b
}
//乘法法运算
fun mutl(a: Int, b: Int): Int {
  return a * b
}
//除法运算
fun devide(a: Int, b: Int): Int {
  return a / b
}

2字符串的比较
Kotlin中的相等运算符有三个 ==, ===, equals()
Kotlin 中的 == 等同于调用 equals() 函数, 默认比较的是两个对象的HashCode.
比较两个对象引用是否相等要用 === 操作符.

var strq1 = "张三"
var str2 = "张三"
var an="Android"
var and = "android"
println(strq1==str2)// true
/**
 * 下面的第二个参数(true/false)
 * 如果是false 表示不忽略大小写
 * 如果是true 表示忽略大小写
 */
println(an.equals(and,false)) //打印出来为false
println(an.equals(and,true))  //打印出来为true

如果两个字符串内容相同那么 ==, equals return true.
如果两个引用相等则 === return true.

// 字符串比较.
private fun test1() {
   val s1 = "Doug"
   // 使用这种方式创建就是为了创建两个地址不同的字符串。
   val s2 = String(charArrayOf('D', 'o', 'u', 'g'))
   println(s1)
   println(s2)
   // 如果两个字符串的值相同那么hashCode也相等.说
   println(s1.hashCode())
   println(s2.hashCode())
   // == <==> equals , 比较的都是字符串的值。
   println(s1 == s2)
   println(s1.equals(s2))
   // === 比较两个对象的引用是否相同。
   println(s1 === s2)
}

如果没有重写 equals 方法那 === 和 == 一样的返回的都是比较引用.
可以重写 equals 然后添加自己的逻辑

class Person(val name:String) {
   /**
    * equals 通用写法.
    */
   override fun equals(other: Any?): Boolean {
   return when (other) {
     !is Person -> false
     else -> this === other || this.name == other.name
   }
  }
}

3 String中的占位符${}

/日记生成器(接收参数是地点,返回内容)
/**
 * ${} string中的占位符
 */
fun diaryGenerater(placeName: String): String {
  var temple = """今天天气晴朗,万里无云,我的小金鱼淹死了,${placeName}  ${placeName.length}个字"""
  return temple
}

调用

var diaryGenerater = diaryGenerater("我好伤心")
println(diaryGenerater)

4条件控制语句(if/else)

fun checkFace(score: Int) {
  if (score > 80) {
println("这是一个帅哥")
  } else {
println("这是一个衰哥")
  }
}
//返回两个数中最大的那个
fun returnBig(a: Int, b: Int): Int {
  if (a > b) {
return a
  } else {
return b
  }
}

也可以写成这样

fun maxOf(a: Int, b: Int) = if (a > b) a else b

String占位符和条件控制语句的联合调用

println("${10}和${12}中较大的那个值为${returnBig(4, 6)}")

字符串与数字之间的转换

var a="13"
var b=13

//数字转字符串
a=b.toString()

//字符串转数字
b=a.toInt()


var c="a3"

b=c.toInt()//编译不报错,但是运行会报NmuberFormatException

四 kotlin对于空指针的处理

kotlin中

?:表示当前是否对象可以为空

!!: 表示当前对象不为空的情况下执行

使用一个返回值为空的函数:

fun parseInt(str: String): Int? {
  return str.toIntOrNull()
}

fun printProduct(arg1: String, arg2: String) {
  val x = parseInt(arg1)
  val y = parseInt(arg2)

  // ...
  if (x == null) {
println("Wrong number format in arg1: '${arg1}'")
return
  }
  if (y == null) {
println("Wrong number format in arg2: '${arg2}'")
return
  }

  // x 和 y 将会在空值检测后自动转换为非空值
  println(x * y)
}

五 区间/for循环/步长/反转/总数

1 区间
声明了一个数组,数组中的值为1,2,3...100

var nums=1..100 
var num=1..100 //闭区间 [1,100]
var num2=1 until 100 //开区间[1,100)

2 for循环
利用 in 将区间中的值取出来

var nums=1..100 
var result=0
for (num in nums){
  result+=num
}
println("结果:${result}")

3 步长 (step)

var nums1=1..16
for (a in nums1 step 2){  //step 步长
   println(a) //1,3,5,7,9,11,13,15
}

4 反转(reversed)

var nums1=1..16
var reversed = nums1.reversed()
for (a in reversed){
   println(a)//15,13,11,9,7,5,3,1
}

5 总数(count)

println("总数为:"+reversed.count())

六 when表达式

和java中的switch有异曲同工之处,但比switch更加强大,更加方便

//学生考试成绩
fun gradeStudent(score:Int) {
  when (score) {
    10 -> println("考了满分")
    9 -> println("干的漂亮")
    8 -> println("还可以")
    7 -> println("还需努力")
    6 -> println("刚及格")
    5 -> println("你完了")
  }
}

调用

 gradeStudent(9)

还可以这样用

//数字长度
fun numTochinese(num:Int):String{
  var result=when(num){
    1->"一"
    2->"二"
    3->"三"
    4->"四"
    5->"五"
    6->"六"
    else->num.toString()
  }
  return result
}

调用

//日记
  fun diaryGenerator(placeName:String){
    var diary="""今天天气不错,我们去${placeName}游玩,首先映入眼帘的是,${placeName} ${numTochinese(placeName.length)}个鎏金大字"""
    println(diary)
}
diaryGenerator("颐和园")

七 人机交互之键盘输入/try

while (true) {
  println("欢迎使用我的计算器")
  println("请输入第一个数字")
  var number1 = readLine()
  println("请输入第二个数字")
  var number2 = readLine()
  //如果这样直接输出,会被当成是string类型的
  println("${number1}+${number2}=${number1 + number2}")
  try {
        //在类型后面跟?表示这个对象可能为空,跟!!表示这个类型一定不为空
        var num1: Int = number1!!.toInt()
        var num2: Int = number2!!.toInt()
        println("${num1}+${num2}=${num1 + num2}")
      } catch (e: Exception) {
        println("大哥请输入数字额")
  }
}

八 集合

1 声明List集合

var lists = listOf<String>("买鸡蛋", "买大米", "买杜蕾斯")

正常打印

for (list in lists) {
  println(list)
}

按位置打印list中的数据

for ((i, e) in lists.withIndex()) {
 println("$i $e")
 //-----0 买鸡蛋
 //-----1 买大米
 //-----2 买杜蕾斯
 /**
  * so i 代表索引位置,e 代表索引对应的值
  */
}

2 声明Map集合

var map = TreeMap<String, String>()
map["好"] = "good"
map["学习"] = "study"
map["天"] = "day"
map["向上"] = "up"

获取里面的内容

println(map["好"]) //----------good

九 递归/尾递归优化

阶乘

fun fact(num:Int):Int{
  if (num==1){
    return 1
  }else {
    return num * fact(num - 1)
  }
}

调用

println("${fact(10)}")

相加

fun add(num:Int):Int{
  if (num==1){
    return 1
  }else{
    return num+ add(num-1)
  }
}

调用

 println("${add(100)}")

尾递归优化时返回的需要时函数本身

同样是相加

tailrec fun adds(num:Int,result:Int):Int{
   println("计算机运行了第${num}次,result=${result}")
  if (num==0){
    return 1
  }else{
    return adds(num-1,result+num)
  }
}

调用

var result=0
println(adds(10000,result))

十 函数

定义一个函数接受两个 int 型参数,返回值为 int :

fun sum(a: Int , b: Int) : Int{
    return a + b
}
fun main(args: Array<String>) {
  print("sum of 3 and 5 is ")
  println(sum(3, 5))
}

函数表达式

var i={x:Int,y:Int ->x+y}
var result=i(3,5)

函数的第二种声明

var j:(Int,Int)->Int={x,y->x+y}
var result2=j(3,5)

如果大括号中的业务逻辑只有一行,可以将大括号省略,然后直接返回函数(如add)

fun add(x:Int,y:Int):Int{
  return x+y
}

Unit 的返回类型可以省略:

fun printSum(a: Int, b: Int) {
  println("sum of $a and $b is ${a + b}")
}

fun main(args: Array<String>) {
  printSum(-1, 8)
}

函数只有一个表达式函数体以及一个自推导型的返回值:

fun add1(x:Int,y:Int):Int=x+y
fun a(x:Int,s:Int):Boolean=x>s

或者

fun sum(a: Int, b: Int) = a + b

更多精彩内容,请关注小编的公众号


jilab.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容