Kotlin从入门到精通(补充中

一.处理Kotlin代码的方式

1.Kotlin Playgroud         在对应网站trykotlinlang.org上在线试用,不用Andriod框架依赖性

2.Andriod Studio |File|Setting|Plugins|Install JetBrains plugin..|Kotlin下载在2.x版本下,3.x则不用,在Tools|Kotlin|Configuration Kotlin in Project

       选择Andriod with  Gradle 然后再选择所需模块和Kotlin版本,3.0之后可在创建项目时选中Include Kotlin support

 

 

3.使用Java-Kotlin转换器J2K

二.Kotlin语言基础知识

1.Kotlin 定义两种数据类型: var:可变引用,可在初始化后更新

                                              val:只读引用,初始化之后无法赋值

val变量相当与final修饰的Java变量,防止被错误修改,多线程工作时,可以不必担心数据同步操作,@val无法改变指向特定对象实例的引用,但可以修改对象的属性

var list = mutableListOf("a","b","c")//ok
list = mutableListOf("d")//error
list.remove(3)//ok

2.类型推断

var title :String

当变量声明和初始化一起执行,可忽略类型声明

var title:String="Kotlin"

类型推断会导致title = 12报错

Kotlin有类型体系结构,全部显性继承Any类型,相当与Java的对象,有equals、toString、hashCode

在Android Studio中可以用Shift+Ctrl+P快捷键知道类型,类型推荐机制同样可以用于泛型

var persons = listOf(personInstancel1,personInstancel2)
//equal to List<Person>
var pair = "Everest" to 8848
//equal to Pair<String,Int>
var pair = Pair("Ever",8848)
//use constructor
   二元参数判断取基本类型String和Int最近的Any类型

必要时可以显性定义数据类型var age: Long = 18

省内存可以用Short

3.严格的空保护机制

在Java中的NullPointerExceptions,大多数不是运行期错误,所以Kotlin加入默认情况下不能设置为空值和存储空引用,除非显性定义

//在变量类型声明加?
val age:Int = null//error
val name:String? =null//ok
//但是潜在空对象无法调用其方法
name.toUpperCase()//error
//需要在调用前加判断

3.Kotlin安全调用 val locked: Bollean? = savedInstanceState?.getBoolean("locked")

4.elvis操作符 first operand?:second operand 如果第一个操作数不为null返回否则第二个

5.let 可空变量处理方式

savedInstanceState?.let{

//ok
}
//当不为空执行let之后的代码

6.处理空指针的例子

val textView = findViewById(R.id.textView) as TextView//不可空

val textView = findViewById(R.id.textView) as TextView?//可空

7.转换

Kotlin采用as关键字为转换操作符,处理转换问题

val fragment: Fragment = ProductFragment()

val productFragment: ProductFragment = fragment as ProductFragment//将上面的fragment转变成ProductFragment

非安全型转换as:无法实现,抛出ClassCastException异常

安全型转换 as?:无法实现,返回null

Kotlin支持to+类型名

智能转换   隐性转换 

//Fish继承Animal并有自己的方法isHungry()
if(animal is Fish){

                 animal.isHungey()//此时为fish


             }

                animal.isHungey()//error 此时为animal

在&&和判空可以应用

fun setView(view :View?){
    view ?:throw RunTimeExceptions("View is empty")
    //is non-nullable
    view.isShown()
}

8.基本数据类型

Byte?、Char?,为"装箱"型表达方式,但是这种方式比较耗内存,对表和数组来讲,影响尤为明显,对於单变量来说就不用担心表达形式

Kotlin针对数字的处理方式不同,数字间没有隐式转换,较小的类型不能隐式转变为较大类型

var weight: Int = 12
var truckweight: Long = weight//error
var truckweight: Long = weight.toLong()
//正确形式


//Kotlin 可以推断类型
val a: Int =1
val b =a+1 //inferred b is Int
val b = a+1L //inferred b is Long 

Kotlin 不支持8进制

9.数组

val array = arrayOf(1,2,3)
//建立数组
val array2:Array<Short> = arrayOf(1,2,3)
val array3:Array<Long> = arrayOf(1,2,3)


val array = arrayOf(1,2,3)//Long数据元素的泛型数组
val array = longArrayOf(1,2,3)//包含Long 数据元素的数组

//kotlin可以指定数组的实际尺寸
val array = arrayOfNulls(3)

val array = Array(5){it*2}//lambda表达式
println(array)  // Prints: [ 0,2,4,8,10] 

10.字符串

方法可以参考String类文档

val name = "Eva"
val message = "My name is $name"
//$符号将变量置于字符串之中
val message = "My name has ${name.length} characters"

11.数组遍历

val intRange = 1..4//equal to i>=1&&i<=4
val charRange = 'b' .. 'g'

默认步进值为1
for(i in 5 downTo 1) print(i) // 逆向遍历
for(i in 3..6 step 2) print(i)//Prints:35
step设置步长

12.Kotlin为面向表达式语言 var speed = vcurrentSpeed  + getAcceleration()

13.if表达式:println(if(x>10)"greater"else"smaller")

                     val greeting =if(hour<18){

                                               "Good day"

                                           }else {

                                            "Good evening"

                                          }

                      val  message = "You are ${ if(age < 18)"young"else "of age"} 

                      println(message)

14.when表达式,相当与if表达式,但是else 是必需的,要覆盖全部情况

val vehicle = "Car"

when(vehicle){
   "Car" , "Bike" -> print("Vehicle")
    else ->print("Unmatch")
}
//逗号分开两种不同的情况,


//when还可以判断变量类型
val vehicle = "Car"

when(vehicle){
   is String->
   is User->
}

//检验特定值范围
val risk = when(risks){
    in 1..20 ->"small risk"
    !in 21..40->"minor risk"
    !in 41..60 ->major risk"
    else->"undefined risk"
}
println(risk)

/* 重要一点如果条件包含所有,可以不加else ,编译器会帮你解决问题*/

15.Kotlin循环 for ( item in array){

                              print(item)

                         }

可以根据索引,withIndex库方法,可返回IndexedValue属性列表,其中包含一个索引和一个数值

for(  (index,value) in array.withIndex() ){

    println("Element at $index is $value")

}

其他如while break continue do...while 与java类似

break 语句提供标注形式

val charRange = 'A'..'B'
val intRange = 1..6
outer@ for(value in intRange){
   println("Outer loop : $value ")
   
   for(char in charRange){
          if(char == 'B')
                break@outer
              
            println("$char")
     {
 }
//prints 
Outer loop: 1
A
break@outer 跳到标记循环之后的语句

16.异常处理          Kotlin中全部异常均为非检查型

fun foo(){
   throw IOException()
}



fun bar(){
   foo()//no need to try-catch block
}



/* Kotlin try表达式定义为表达式,可以返回值*/
//Android 检验是否成功安装
val result = try {
  context.packageManager.getPackageInfo("com.text.app",0)
}catch(ex: PackageManager.NameNotFoundException{
  false
}

Kotlin try表达式定义为表达式,可以返回值

17. val只有只读性质,在大多数时候可将其视做常量,初始化过程可能延迟

const val MAX_LOG_ENTRIES = 100
     @MyLogger(MAX_LOG_ENTRIES)
    // value availiable at compile time
     class Test{}
//保证在编译期已知,用const关键字

三、函数

1.定义函数

fun main(args: Array<String>){
        println("Hello,World!")
}
fun double(i : Int): Int{
        return 2*i
}

2.返回函数的形式

fun printSum(a:Int,b:Int): Unit{//不返回值
    val sum = a+b
    print(sum)
}
fun printSum(a:Int,b:Int): Int{//返回Int
   return sum
}

3.vararg参数

可以传任意数量的参数,正常状态下,期待为加载特定类型的泛型数组

fun print Sum(vararg numbers: Int){
         val sum = numbers.sum()
         print(sum)
}
printSum(1,2,3,4,5)//Prints:15
printSum()//Prints:0
fun printAll(vararg texts: Any){
        val allTexts = texts.joinToString(",")
        println(allTexts)
}
//Usage
printAll("A",1,,'c')//Prints: A,1,c

4.单表达函数

fun square(x:Int):Int = x*x
//在安卓项目中根据布局
class AddressAdapter : ItemAdapter<AddressAdapter.ViewHolder>(){
    override fun getLayoutId() = R.layout.choose_address_view
    override fun onCreateViewHolder(itemView : View)
    ViewHolder(itemView)
}
//独立对象上的链接多项操作
fun textFormatted(text: String,name: String) = text
                 .trim()
                 .capitalize()
                 .replace("{name}", name)
val formatted = textFormated("hello,{name}","Marcin")
println(formatted)
             

5.命令式编程和声明式编程:  命令式编程范例描述了所需的实际步骤,进而执行某项操作

                                                声明式编程范例描述了期望结果,但无须按照步骤予以实现(行为实现),程序通过表达式或声明

                                        来实现

6.尾递归函数:

tailrec fun getState(state: State, n:Int):State = 
        if(n<=0) state
        else getState(state.nextState(),n-1)

尾递归函数无需担心StackOverflowError,可通过编译器优化递归调用

//尾递归工作方式
public static final State getState(@NotNull State state, int n)
{
      while(true){
                if(n<=0)return state;
                state = state.nextState();
                n=n-1;
               }
}

7.默认参数值

fun printValue(value: String,prefix:String="",suffix:String=""){
        print(prefix)
        print(value)
        println(suffix)
}
printValue("str")//Prints: str
printValue("str","(",")")//Prints: (str)

8.命名参数语法

对于Kotlin参数,命名参数语法还具有额外的特征,当改变某个参数名时,也许会由于该名称会用于其他项目中,因而将会产生错误。使用命名参数语法,Kotlin库生成器一般会对此谨慎处理

9.顶级函数

//Printer.kt
fun PrintTwo(){
    print(2)
}

//将代码编译为Java字节码
public final calss PrintKt{
           public static void printTwo(){
                     System.out.print(2)
           }
}

10.顶级函数的底层机制

@file:JvmName("Printer")

相当与java引入Printer.java文件

@file:JvmName("Math")引用数学帮助函数 

用修改生成类名的JvmName注解十分有用,有助于解决命名冲突问题

11.局部函数

fun makeStudentList() : List<Student>{
   var students: List<Student> = emptyList()
   fun addStudent(name:String,state:Student.State = 
                  Student.State.New){
             students +=Student(name,state,courses = emptyList())
    }
  //...
  addStudent("Ada")
  addStudent("Donald")
 //...
 return students
}

12.无返回类型

函数可简化错误抛出机制,如throwError

fun fail () :Nothing = throw Error()

简化单元测试中的错误机制

Nothing是所有类型的子类型,即可空类型和非空类型,同时这也是Nothing被称作空类型的原因,意味着不存在任何值在运行期内包含该类型,无法形成Nothing实例,仅存在从函数返回的错误信息,将其作为返回类型。对于Nothing来说,没有必要添加任何内容以对该类型产生影响

 四、类和对象

1.定义类

在Kotlin中是用class关键字定义的 ex. class Person

                                                            val person = Person()

在Kotlin文件中无需使用new关键字,在Java文件中使用new 关键字

2.属性

Kotlin用constructor方法相当于Java类的构造方法,替代方法是可以用init代替constructor

//1
class Person{
      var name: String
      var age:Int
       
      constructor(name:String, age:Int){
            this.name = name
            this.age  = age
        }
}



//2
class Person constructor(name:String, age:Int){
      var name: String
      var age:Int
       
      init{
            this.name = name
            this.age  = age
        }
}

3.读-写形式 和 只读属性

用val 关键字 仅生成 getter方法

Kotlin不支持只写属性

4.属性访问语法

Car car = new Car(7.4)

car.setSpeed(9.2)

Double speed = car .getSpeed

5.自定义getter/setter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章