Kotlin 基础学习 关键字

Posted CrazyApes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 基础学习 关键字相关的知识,希望对你有一定的参考价值。

Kotlin
线上编写练习
Kotlin官网提供了 PlayGround 供大家线上尝试
地址:https://play.kotlinlang.org/

原文:https://blog.csdn.net/CrazyApes/article/details/126941878

文章目录

前言

本来没打算把关键字介绍放在第一部分,可是发现,如果不放在这儿,后面很多用到关键字的地方会有很多不明白不了解的情况。
所以还是把关键字的介绍放在了第一部分,不需要全部记住,但是在后面看到的时候,可以随时翻到这篇文章,可以做一个简单的了解。
本文简单的介绍了Kotlin中使用的部分常用关键字。
希望对大家初步了解Kotlin有所帮助。

关键字

Kotlin 官网文档
Keywords
https://kotlinlang.org/docs/keyword-reference.html

Kotlin 的关键字大致可以分为 三类

  • Hard keywords 硬关键字
    任何情况下都被优先解析为关键字,不可以作为任何标识符。
  • Soft keywords 软关键字
    在某些起作用的上下文中作为关键字,在其不起作用的上下文中可以作为标识符使用。
  • Modifier keywords 修饰符关键字
    可以作为修饰符的关键字,也可以在其它地方用作标识符
  • Special identifiers 特殊标识符
    可以由编译器在特定上下文中定义,它们可以在其他上下文中用作常规标识符
  • Operators and special symbols 运算符和特殊符号
    一些常见运算符和特殊符号

硬关键字HardKeywords

Kotlin 官网文档
Hard Keywords
https://kotlinlang.org/docs/keyword-reference.html#hard-keywords)

下面的这些符号任何情况下都被优先解析为关键字,不可以作为任何标识符。

// 数据类型转换 
val obj: Any = 1
// 可能会抛出 java.lang.ClassCastException,可以考虑 is 或者 as? 替代
val intValue: Int = obj as Int 

// 处理Nullable
val intValueNullable: Int? = obj as? Int
// is 之后可以直接使用对应属性
if (obj is Int) 
    print("$obj.plus(1)")

==================================================
// import 别名设置
import com.unluck.ktdemo.DemoClass
import com.unluck.ktdemo.bean.DemoClass as DemoBean // 同时引入DemoClass会冲突,可以考虑通过别名引入
//  空安全,但是需要处理 Nullable
val obj: Any? = null
val intValueNullable: Int? = obj as? Int
// break 终止 for
for (i in 1..100) 
    if (...) break


// break to labels 可以声明labels 终止指定的for循环
breakToThis@ for (i in 1..100) 
    for (j in 1..100) 
        if (...) break@breakToThis // 终止 breakToThis@ for(i)
    

// 声明类 DemoClass 
class DemoClass  
// 声明类 MainActivity 并继承自 AppCompatActivity
class MainActivity : AppCompatActivity() 
 // 声明类 DemoTextView 并继承自 AppCompatTextView
class DemoTextView(ctx : Context) : AppCompatTextView(ctx)
// 声明数据类 DemoBean 并实现 Serializable 接口
data class DemoBean(val name: String) : Serializable
// 同break使用方式类似
for (i in 1..100) 
    if (...) continue
 

// continue to labels 可以声明labels 继续指定的for循环的下一个循环
continueToThis@ for (i in 1..100) 
    for (j in 1..100) 
        if (...) continue@continueToThis
    

do 
    ...
 while (true)
  • else 定义一个 if 表达式 的 false 时的执行分支.
if (...) 
    ... 
else 
    ...
val bool : Boolean = false
for (i in 1..100) 
    print("print i = $i")
 
fun mainFunction() 
    ...

if (i == 0) ... 
// for 迭代
for (i in 6 downTo 0 step 2) 
    println(i)


// check in range
if (3 in 0..4)

// check contains
val list = arrayListOf<Any>()
if ( "1" in list ) 
    ...


// when branch
val num = 3
when 
    num in 0..4 -> print("the num $num is in range 0-4")
    else -> 


// 逆变参数
interface Comparable<in T> 
    operator fun compareTo(other: T): Int

  • !in
    • 用作 infix 中缀操作符检查值不属于 range, 集合类, 或者其它 定义了 ‘contains’ 方法 的实体类.
    • 一般就是用于 when 表达式的不属于,和上面用于 when 表达式的含义相反.
// check not in range
if (6 !in 0..4)

// check contains
val list = arrayListOf<Any>()
if ( "1" !in list ) 
    ...


// when branch
val num = 7
when 
    num !in 0..4 -> print("the num $num is not in range 0-4")
    else -> 


interface Comparable<in T> 
    operator fun compareTo(other: T): Int

// check value typecasts
if ( obj is Int) 
    ...

// when branch 
when (value) 
    is GroupMsg -> print("this is group message")
    else -> print("other message")


  • !is

    • 跟上面is功能相对
  • null 就是null啊,表示对象没有任何对象引用.

val nullableValue : Any? = null
// 全局单例
object SingletonClass 
    var mInstanceValue = 999

    fun singletonFunString() = "Singleton Class"


// 伴生对象
class DemoUtil 
    companion object 
        @JvmStatic
        fun companionObjectFun() = "this is companion object function"
    


// 对象表达式 -> 某个Any对象
val helloWorld = object 
    val hello = "Hello"
    val world = "World"
    // object expressions extend Any, so `override` is required on `toString()`
    override fun toString() = "$hello $world"


// 对象表达式 -> 实现某个接口
window.addMouseListener(object : MouseAdapter() 
    override fun mouseClicked(e: MouseEvent)  /*...*/ 

    override fun mouseEntered(e: MouseEvent)  /*...*/ 
)

// 对象表达式 -> 实现抽象类
open class A(x: Int) 
    public open val y: Int = x

interface B  /*...*/ 

val ab: A = object : A(1), B 
    override val y = 15

// package 仅代表当前文件所属的 package 属性
// 与 java 相比,其package无需与文件的实际路径相关,但是建议保持一致。
package com.unluck.ktdemo.bean  // file://com/unluck/ktdemo/data
// 同 java 类似,从当前函数返回
fun foo() 
    listOf(1, 2, 3, 4, 5).forEach 
        if (it == 3) return // non-local return directly to the caller of foo() 
        print(it)
    
    println("this point is unreachable")
 // result -> 12

// 在 forEach 中使用 labels 则类似 continue , 其实 return 的是执行的 lamda 
fun foo() 
    listOf(1, 2, 3, 4, 5).forEach lit@
        if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop
        print(it)
    
    print(" done with explicit label")
 // result -> 1245 done with explicit label

// 调用超类方法
class Circle() : Shape() 
     override fun draw() 
        super.draw()
        println("Circle")
    

// 调用超类构造
class DemoView : View 
    constructor(ctx: Context) : super(ctx)
    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)

throw NoBugException()
val bool : Boolean = true
try 
    ...
 catch ( e : Exception) 
class A 
    inner class Inner

class B 
    inner class Inner


typealias AInner = A.Inner
typealias BInner = B.Inner
  • typeof 保留关键字,暂时没用,可能以后会用.

  • val 声明不可变变量 (只读) 属性 或者 局部变量.

val finalValue : Int = 1
var variable : Int = 1
when 
    a == b -> 
    else -> 


when(a) 
    0 -> 
    else -> 

while (true) 
    ...

软关键字SoftKeywords

Kotlin 官网文档
Soft Keywords
https://kotlinlang.org/docs/keyword-reference.html#soft-keywords)

下面的这些符号在其适用的上下文中充当关键字,并且可以在其他上下文中用作标识符。

interface Printer 
    fun print()


class DefaultPrinter : Printer 
    override fun print() 
        print("default printer")
    


class DemoFragment : Fragment(), Printer by DefaultPrinter()   // 委托实现接口
    val vm : ViewModel by viewModels() // 委托属性

    fun doSomePrint() 
        print() // print -> default printer
    

try 
    ...
    throw NoBugException("Yes , NO BUG !!! ")
    ...
 catch (e : NoBugException) 
    print("NO BUG ~ ")
 catch (e2 : Exception) 
    print("F..k !!!! ")

class DemoView : View 
    constructor(ctx: Context) : super(ctx) 
        ...
    
    constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)

try 
    ...
 finally 
    // optional finally block
 
val isEmpty: Boolean
    get() = this.size == 0
import com.unluck.ktdemo.Demo
class Demo 
    init 
        print("init block")
    

var setterVisibility: String = "abc"
    private set // the setter is private and has the default implementation

var setterWithAnnotation: Any? = null
    @Inject set // annotate the setter with Inject
// To declare an inline class, use the value modifier before the name of the class:
value class Password(private val s: String)
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
    where T : CharSequence,
          T : Comparable<T> 
    return list.filter  it > threshold .map  it.toString() 

修饰关键字ModifierKeywords

Kotlin 官网文档
Modifier keywords
https://kotlinlang.org/docs/keyword-reference.html#modifier-keywords)

以下符号作为声明中修饰符列表中的关键字,并可用作其他上下文中的标识符。

  • abstract 标记为 抽象类 或者抽象方法.

  • actual 多平台 实现方式,该标记表明其实现方式可能由其它平台实现.

@SinceKotlin("1.1") public actual typealias RandomAccess = java.util.RandomAccess


@SinceKotlin("1.1") public actual typealias ArrayList<E> = java.util.ArrayList<E>
@SinceKotlin("1.1") public actual typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V>
@SinceKotlin("1.1") public actual typealias HashMap<K, V> = java.util.HashMap<K, V>
@SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>
@SinceKotlin("1.1") public actual typealias HashSet<E> = java.util.HashSet<E>
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
        AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER,
        AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class Fancy
class DemoClass 
    companion object Factory 
        fun create(): DemoClass = DemoClass()
    

const val STATIC_FINAL_STRING: String = "public static final String"
public inline fun <T, R : Comparable<R>> Iterable<T>.sortedBy(crossinline selector: (T) -> R?): List<T> 
    return sortedWith(compareBy(selector))

// 编译器会自动为其主构造函数中的属性生成 equals ,hashCode,toString,copy等方法
data class DataBean (
    val name : String = "",
    val age  : Int = 0,
    var nick : String = "",
) : Serializable
enum class Color(val rgb: Int) 
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)

  • expect 将一个声明标记为平台相关, 并期待在平台模块中实现.

  • external 将一个声明标记为不是在 Kotlin 中实现(通过 JNI访问或者在JavaScript中实现).

  • final 禁止 重写方法.

open class Rectangle() : Shape() 
    final override fun draw()  /*...*/ 

@file:kotlin.jvm.JvmName("TuplesKt")
package kotlin
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)

// use to 
val pair : Pair<String,String> = "A" to "B"
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("MapsKt")
@file:OptIn(kotlin.experimental.ExperimentalTypeInference::class)

package kotlin.collections

@SinceKotlin("1.1")
@kotlin.internal.InlineOnly
public inline fun <K, V> hashMapOf(): HashMap<K, V> = HashMap<K, V>()
  • inner 标识 内部类 会持有外部引用.
// kotlin 默认非声明 inner 的 class 为静态内部类
// 因此如需持有外部引用,需要单独添加 inner 标识
class Outer 
    private val outValue: Int = 1
    inner class Inner 
        fun print() = outValue
    


val print = Outer().Inner().print() // print == 1
package kotlin.collections

expect interface RandomAccess

...

internal expect fun copyToArrayImpl(collection: Collection<*>): Array<Any?>

internal expect fun <T> copyToArrayImpl(collection: Collection<*>, array: Array<T>): Array<T>

internal expect fun <T> arrayOfNulls(reference: Array<T>, size: Int): Array<T>
internal expect fun <K, V> Map<K, V>.toSingletonMapOrSelf(): Map<K, V>
internal expect fun <K, V> Map<out K, V>.toSingletonMap(): Map<K, V>
internal expect fun <T> Array<out T>.copyToArrayOfAny(isVarargs: Boolean): Array<out Any?>
class DemoClass 
    lateinit var lateValue : DemoBean

    fun doLateInit() 
        if (!this::lateValue.isInitialized) 
            lateValue = DemoBean()
        
    

open class Person 
    open fun age() = 10

class OldMan : Person() 
    override fun age() = 100

  • operator 将方法声明为 重载运算符 或 约定运算.
    Kotlin 约定了一些函数规则,与之对应的有一系列运算符或者其它关键字约定。
    详细可参考官网对应文档,这里不再一一指出。
  • out 标记参数类型为 协变.
    表示告诉编译器,你只操作数据,并不变更消费数据,不关心其类型。
public data class Pair<out A, out B>(
    public val first: A,
    public val second: B
) : Serializable
open class Person 
    open fun age() = 10

class OldMan : Person() 
    override fun age() = 100

@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
    noinline ownerProducer: () -> ViewModelStoreOwner =  this ,
    noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class,  ownerProducer().viewModelStore , factoryProducer)
  • sealed 声明一个 密封类 (限制其继承关系).

  • suspend 标识一个方法或者 lamda 可被挂起 (在 协程 中使用).

public suspend fun delay(timeMillis: Long) 
    if (timeMillis <= 0) return // don't delay
    return suspendCancellableCoroutine sc@  cont: CancellableContinuation<Unit> ->
        cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont)
    

// mutableListOf
public fun <T> mutableListOf(vararg elements: T): MutableList<T> =
    if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))

// vararg
val list = mutableListOf(1,2,3,4)

未完待续

以上是关于Kotlin 基础学习 关键字的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 基础学习 关键字

Kotlin 基础学习 关键字

Kotlin:使Java函数可调用中缀

Kotlin学习与实践 基础

Kotlin学习笔记——接口抽象类泛型扩展集合操作符与Java互操作性单例

Kotlin挂起函数基础