kotlin 语法

kotlin 语法

map的初始化

val map = mapof("a" to 2)

延迟属性

val  p : String by lazy {}

扩展函数

fun String.toBasethree(){
}

创建单例

object Resource {
  val name = "name"
}

映射可空值

val mapped = Vlaue?.let{ transformValue(it)}? : defaultValueIfValueIsNull

try/catch

func test(){
  val result = try{
    count()
  }catch{
    throw IllegaStateException()
  }
}

单表达式函数

fun theAnswer() = 42

基本类型

数字

Double 64
Long 64
Float 32
Int 32
Short 16
Byte 8

字面常量

Long 123L
0x0f  //十六进制
0b000001011 //二进制

数字类型转换

toByte():Byte
toShort():Short
toInt():Int 
toLong():Long
toFloat():Float
toDouble():Double
toChar():Char

位运算符 只适用于Int long

shl(bits)  <<
shr(bits) >>
ushr  >>> //无符号右移
and   &
or    |
xor   
inv   位非

特殊字符 需要\ 转意

类和对象

接口

interface  

可修饰符

private protected interface public

扩展函数

fun MutableList<Int>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // “this”对应该列表
    this[index1] = this[index2]
    this[index2] = tmp
}

fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // “this”对应该列表
    this[index1] = this[index2]
    this[index2] = tmp
}

半生对象的扩展 (没有理解在哪些地方用到)

class MyClass {
  commpanion 
}

数据类

只保存数据的类 叫做数据类

data class User(val name: String, val age: Int)

泛型

class Box<T>(tab:T){
  val vlaue = tab
}

范型的约束

fun <T:Comparable<T>> sort(list:List<T>)

嵌套类和内部类

Class Outer {

  private val bar : Int = 1
  class Nested {
   fun foo() = 2 
  }
}

val demo = Outer.Nested().foo() // ==2

内部类

class Outer {

  private var bar : Int = 1
  inner class Inner{
    fun foo() = bar
  }
}

val demo = Outer().Inner().foo() // == 1

匿名内部类

window.addMouselListener(object:MouseAdapter(){

  override fun mouserClicked(e:MousEvent){

  }

  override fun mouseEntered(e : MouseEvent){

  }
})

枚举类

enum class Direction {
  NoRTH,SOUHT,WEST,EAST
}

枚举常量也可以声明自己的匿名类

enum class ProtocolState {
  WAITIng {
    override fun singla() = TALKING
  }

  TALKING {
    override fun singal() = WAIING
  }

  abstract fun singal : ProtocolState
}

委托属性

语法是:

val <属性名> :<类型> by <表达式>  在by 后面的表达式就是该委托  因为属性对应的get() 和 set() 会被委托给它的 getValue() 和 setValue() 方法。 



class Example {
    var p: String by Delegate()
}

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}

// 实例get
val e = Example()
println(e.p)  //Example@33a17727, thank you for delegating ‘p’ to me!

//set
e.p = "NEW"  //NEW has been assigned to ‘p’ in Example@33a17727.

延迟属性Lazy

lazy() 是接受 一个lambda 并返回一个 Lazy 实例的函数 返回的实例可以作为实现延迟属性的委托 第一次调用get() 会执行已传递给lazy() 的 lambda 表达式并记录结果 后续调用get() 只是返回记录的结果

val lazyValue : String by lazy {
  print("computed!")
  "hello"
}

fun main(args: Array<String>){
    printIn(lazyValue)
    printIn (lazyValue)
}

可观察的属性 Observable

Delegates.observable() 接收两个参数 初始值 和 修改时 处理程序(handler) 每当我们给属性赋值时会调用该处理程序(在赋值后执行)。它有三个参数:被赋值的属性、旧值和新值:

import kotlin.properties.Deleagates
class User {
  // 观察模式
  var name : String by Delagates.observable(""<no name>""){
    prop, old, new ->
    printIn("$old -> $new ")
  }

  fun main(args:Array<String>){
    val user = User()
    user.name = "first"
  }
}

委托属性

有一些常见的属性类型,虽然我们可以在每次需要的时候手动实现它们, 但是如果能够为大家把他们只实现一次并放入一个库会更好。例如包括:

  • 延迟属性(lazy properties): 其值只在首次访问时计算;
  • 可观察属性(observable properties): 监听器会收到有关此属性变更的通知;
  • 把多个属性储存在一个映射(map)中,而不是每个存在单独的字段中。

为了涵盖这些(以及其他)情况,Kotlin 支持 委托属性:

class Example {
    var p: String by Delegate()
}

语法是: val/var <属性名>: <类型> by <表达式>。在 by 后面的表达式是该 委托, 因为属性对应的 get()(和 set())会被委托给它的 getValue() 和 setValue() 方法。 属性的委托不必实现任何的接口,但是需要提供一个 getValue() 函数(和 setValue()——对于 var 属性)。 例如:

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}

当我们从委托到一个 Delegate 实例的 p 读取时,将调用 Delegate 中的 getValue()函数, 所以它第一个参数是读出 p 的对象、第二个参数保存了对 p 自身的描述 (例如你可以取它的名字)。 例如:

val e = Example()
println(e.p)

输出结果:

Example@33a17727, thank you for delegating ‘p’ to me!

类似地,当我们给 p 赋值时,将调用 setValue() 函数。前两个参数相同,第三个参数保存将要被赋予的值:

e.p = "NEW"

输出结果:

NEW has been assigned to ‘p’ in Example@33a17727.

委托对象的要求规范可以在下文找到。

请注意,自 Kotlin 1.1 起你可以在函数或代码块中声明一个委托属性,因此它不一定是类的成员。 你可以在下文找到其示例。

标准委托

Kotlin 标准库为几种有用的委托提供了工厂方法。

延迟属性 Lazy

lazy() 是接受一个 lambda 并返回一个 Lazy 实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用 get() 只是返回记录的结果。

val lazyValue: String by lazy {
    println("computed!")
    "Hello"
}

fun main(args: Array<String>) {
    println(lazyValue)
    println(lazyValue)
}

这个例子输出:

computed!
Hello
Hello

默认情况下,对于 lazy 属性的求值是同步锁的(synchronized):该值只在一个线程中计算,并且所有线程会看到相同的值。如果初始化委托的同步锁不是必需的,这样多个线程可以同时执行,那么将 LazyThreadSafetyMode.PUBLICATION 作为参数传递给 lazy() 函数。 而如果你确定初始化将总是发生在单个线程,那么你可以使用 LazyThreadSafetyMode.NONE模式, 它不会有任何线程安全的保证和相关的开销。

可观察属性 Observable

Delegates.observable() 接受两个参数:初始值和修改时处理程序(handler)。 每当我们给属性赋值时会调用该处理程序(在赋值后执行)。它有三个参数:被赋值的属性、旧值和新值:

import kotlin.properties.Delegates

class User {
    var name: String by Delegates.observable("<no name>") {
        prop, old, new ->
        println("$old -> $new")
    }
}

fun main(args: Array<String>) {
    val user = User()
    user.name = "first"
    user.name = "second"
}

这个例子输出:

<no name> -> first
first -> second

如果你想能够截获一个赋值并“否决”它,就使用 vetoable() 取代 observable()。 在属性被赋新值生效之前会调用传递给 vetoable 的处理程序。

把属性储存在映射中

一个常见的用例是在一个映射(map)里存储属性的值。 这经常出现在像解析 JSON 或者做其他“动态”事情的应用中。 在这种情况下,你可以使用映射实例自身作为委托来实现委托属性

class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int     by map
}

//  val
val user = User(mapOf(
    "name" to "John Doe",
    "age"  to 25
))


// var 
class MutableUser(val map: MutableMap<String, Any?>) {
    var name: String by map
    var age: Int     by map
}

挂起函数

当我们调用标记有特殊修饰符 suspend 的函数时,会发生挂起:

suspend fun doSomething(foo :Foo): Bar {
}

//
fun main(){
  async {
    doSomething()
  }
}

解构声明

我觉得就是Swift 中的 元组 (value1,value2)

for ((a, b) in collection){
}

for((key, value) in map){
}

val (_ , status)  = getResult()  // 下划线 代表不使用的变量

集合

List Set Map

val list = listof()
val mutlist = mutableListOf()
val setof = setof()
val mutableSetof = mutableSetOf()
val map = mapOf(a to b, c to d)

区间

for (i in 1..10) {   
  println(i) // (1 2, .....,10)
}

for (i in 4 downTo 1) {
  println(i) // 4,3,2,1
}

for (i in 1..4 step 2) {
  printin(2) // 输出 13
}

for (i in downTo 2 step 2) {
   println(i) // 4 2
}

for (i in 1 until 10) {
  println(i) // i in [1,10)
}

//反转
reversed()

// 

类型的检查 和 转换 “is” 和 “as”

类型的检查

// is  和  !is

fun demo(x : Any) {
  if (x is  Strig) {
    print(x.length) // x 自动转换为字符串
  }
}

if (x !is String) return 
println(x.length)

类型转换

// 不安全的转换
val x : String  = y as String

//安全的转换
val s : String = y as String?

// 安全可空的转换
val x : String? = y as? String

This 表达式

要访问来之外部作用域的this 我们需要使用 this@类/扩展函数

class A {

  inner class B {

    fun Int.foo() {
      val a = this@A
      val b = this@B

      val c = this
      val c1 = this @foo
    }

    val funLit = lambda@ fun String.(){
      val d = this
    }
  }

}

相等

引用相等

===
!==

// null == value  不需要优化

操作符重载

操作符重载的函数 需要使用 operator 修饰符号标记

+a  a.unaryPlus()
-a  a.unaryMinus()
!a  a.not()

a++ a.inc()
a-- a.dec()

a + b   a.plus(b)
a - b   a.minus(b)
a * b   a.times(b)
a / b   a.div(b)
a % b   a.rem(b)、 a.mod(b) (已弃用)
a..b    a.rangeTo(b)

a in b  b.contains(a)
a !in b !b.contains(a)

a[i]    a.get(i)
a[i, j] a.get(i, j)
a[i_1, ……, i_n] a.get(i_1, ……, i_n)
a[i] = b    a.set(i, b)
a[i, j] = b a.set(i, j, b)
a[i_1, ……, i_n] = b a.set(i_1, ……, i_n, b)

a() a.invoke()
a(i)    a.invoke(i)
a(i, j) a.invoke(i, j)
a(i_1, ……, i_n) a.invoke(i_1, ……, i_n)

a += b  a.plusAssign(b)
a -= b  a.minusAssign(b)
a *= b  a.timesAssign(b)
a /= b  a.divAssign(b)

a == b  a?.equals(b) ?: (b === null)
a != b  !(a?.equals(b) ?: (b === null))

a > b   a.compareTo(b) > 0
a < b   a.compareTo(b) < 0
a >= b  a.compareTo(b) >= 0
a <= b  a.compareTo(b) <= 0

空安全

kotlin的空安全 和 swift 的 (Optional Type)可选类型相识 强制解包和转化 可能异常

// 如果你有一个可空类型元素的集合 并且想要过滤非空元素 你可以使用 filterNotNull  不知道swift中有没有 没有

val nullableList : List <Int?> = listof(1,2,null,4)
val intlist : List<Int>  = nullableList.filterNotNull()

异常

try / catch

try {

} catch {

}

val a :Int? = try {
   parseInt(input)

} catch(e:NumberFormatEXception ){
  null
}


// Nothing 类型
val s = person.name? : throw
IllegalArgumentExCeption("Name required")

//
fun fail(message : String) : Nothing {
  throw IllegalArgumentException(message)
}

注解

依赖注入是面向对象编程的一种设计模式,其目的是为了降低程序耦合,这个耦合就是类之间的依赖引起的。

举个例子:我们在写面向对象程序时,往往会用到组合,即在一个类中引用另一个类,从而可以调用引用的类的方法完成某些功能,就像下面这样

public class ClassA {
    ...
    ClassB b;
    ...
    public ClassA() {
        b = new ClassB();
    }

    public void do() {
        ...
        b.doSomething();
        ...
    }
}

这个时候就产生了依赖问题,ClassA依赖于ClassB,必须借助ClassB的方法,才能完成一些功能。这样看好像并没有什么问题,但是我们在ClassA的构造方法里面直接创建了ClassB的实例,问题就出现在这,在ClassA里直接创建ClassB实例,违背了单一职责原则,ClassB实例的创建不应由ClassA来完成;其次耦合度增加,扩展性差,如果我们想在实例化ClassB的时候传入参数,那么不得不改动ClassA的构造方法,不符合开闭原则  感觉想C++ 里的声明一样

反射

类引用

// kotlin 的引用
val c = MyClass:: class 

var c = MyClass :: class.java  // java的

//::

fun isOdd(x:Int) = x%2 != 0
val number = listof(1,2,3)
println(numbers,filter(::isOdd)) //输出【1,3】

// ::   this 和 ::this  和 this::  等价

类型别名

类型别名为现有类型提供替代名称。 如果类型名称太长,你可以另外引入较短的名称,并使用新的名称替代原类型名

typealias NodeSet = Set<Network.Node>
typealias FileTable<K> = MutableMap<K,MutableList<File>>

typealias MyHandler = (Int,String,Any)

typealias Predicate<T> = (T) -> Boolean

class A {
  inner class  Inner
}
class B {
  inner class Inner
}

typealias AInner = A.Inner
typealias BInner = B.Inner

关键字 与 操作符

// 不常见的
typealias   // 声明一个类别

by          //将属性访问器的实现委托给另一个对象   
            //将接口的实现委托给另一个对象

constructor //主构造函数和次构造函数
dynamic     // 引用一个 Kotlin/JS 代码中的动态类型
field       // 用作注解使用处目标
file        // 用作注解使用处目标
finally     // 开始一个当 try 块退出时总会执行的块
param       // 用作注解使用处目标
property    // 用作注解使用处目标
receiver    // 用作注解使用处目标

修饰符关键字

actual      //表示多平台项目中的一个平台相关实现
abstract    // 抽象类
annotation  // 注解类
companion   //伴生对象  我觉得可以理解为 stata open class 
const       //编译期间常量
data        //数据类
enum        //枚举
final       // 终类
infix       //允许以中缀表示法调用函数
inline      // 内联
inner       //允许在嵌套类中引用外部类实例

open        //
public      //
protected   //
private     //

operator    //重载一个操作符或者实现一个约定

tailrec    //将一个函数标记为尾递归(允许编译器将递归替换为迭代)

it         //

@         //引入一个注解  引入或引用一个循环标签  
          //引用一个来自外部作用域的 “this”表达式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值