kotlin基础知识点

1.字符串的截取

fun main(args: Array<String>) {
    val text = """
    |多行字符串
    |多行字符串
    """.trimMargin()//使用该函数去除前置空格时需要有边界前缀,边界前缀不打印.直接使用.trim()会只有去除第一行的空格
    println(text)   // 输出有一些前置空格,
}

运行结果:
使用
2. 不支持 “/” 转义

fun main(args: Array<String>) {
    val price = """
    ${'$'}9.99
    """
    println(price)  // 求值结果为 $9.99
}

3. vararg 关键字可变参数

fun vars(vararg v:Int){
    for(vt in v){
        print(vt)
    }
}
// 测试
fun main(args: Array<String>) {
    vars(1,2,3,4,5)  // 输出12345
}

4. lambda关键字 (匿名函数)

// 测试
fun main(args: Array<String>) {
    val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
    println(sumLambda(1,2))  // 输出 3
}

5. NULL 处理

//类型后面加?表示可为空
var age: String? = "23" 
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1

6. 遍历数组

fun main(args: Array<String>) {
    val items = listOf("apple", "banana", "kiwi")
    for (item in items) {
        println(item)
    }

    for (index in items.indices) {
        println("item at $index is ${items[index]}")
    }
}

输出结果:
apple
banana
kiwi
item at 0 is apple
item at 1 is banana
item at 2 is kiwi
7. for 循环的跳步执行及翻转

fun main(args: Array<String>) {
    for (i in 1..4) print(i) //1234
    println()
    for (i in 4 downTo 1) print(i) //4321
    println()
    for (i in 1..4 step 2) print(i) //13
    println()
    for (i in 4 downTo 1 step 2) print(i)//42
    println()
    for (i in 1 until 10) { // i in [1, 10), 不包含 10
        print(i) //123456789
    }
}

8. lable的使用
1.给内侧for-break 添加标签只能打印20~25的数字,只能跳出内侧循环
(可以说这里添加标签相当于没有添加标签,因为break关键字本身就是要跳出所在的循环圈)

fun main(args: Array<String>) {
    for (i in 1..10) {
        loop@ for (index in 20..30){
            print("$index,")
            if (index ==25)break@loop
        }
        print("*$i*")
    }
}

截图有限,结果是循环了10次
在这里插入图片描述
给外侧for-break添加标签可以跳出外侧循环

fun main(args: Array<String>) {
    loop@ for (i in 1..5) {
         for (index in 20..30){
            print("$index,")
            if (index ==25)break@loop
        }
        print("*$i*")
    }
}

只打印一次20~25
在这里插入图片描述
3.给return 添加标签,不添加下面的标签时将结束整个函数,即end不打印

fun main(args: Array<String>){
    val indexes = arrayOf(1, 2, 3, 4, 5, 6, 7)
    //forEach是内联函数
    indexes.forEach loop@ {
        if (it > 5) {
            return@loop
        }
        println(it)
    }
    println("End")
}

在这里插入图片描述
4.注意if语句的条件判断,==return会跳过这次循环,>号是永久性的跳出(与3对比看)

fun returnDemo2(){
    println("START : "+::returnDemo2.name)
    val  intArray = intArrayOf(1,2,3,4,5,6,7)
    intArray.forEach here@{
        if (it == 3) return@here//指令跳转到lambda表达式标签here@处。
        println(it)          //继续下一个it = 4遍历循环
    }
    println(" END : "+::returnDemo2.name)//结果1、2、4、5、6、7
}

在这里插入图片描述
9.field 关键词只能用于属性的访问

class Person {
    var lastName: String = "zhang"
        get() = field.toUpperCase()   // 将变量赋值后转换为大写
        set

    var no: Int = 100
        get() = field                // 后端变量
        set(value) {
            if (value < 10) {       // 如果传入的值小于 10 返回该值
                field = value
            } else {
                field = -1         // 如果传入的值大于等于 10 返回 -1
            }
        }

    var heiht: Float = 145.4f
        private set
}

// 测试
fun main(args: Array<String>) {
    var person: Person = Person()

    person.lastName = "wang"

    println("lastName:${person.lastName}")

    person.no = 9
    println("no:${person.no}")

    person.no = 20
    println("no:${person.no}")

}

输出结果为:

lastName:WANG
no:9
no:-1

10. 匿名内部类

class Test {
    var v = "成员属性"

    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}

/**
 * 定义接口
 */
interface TestInterFace {
    fun test()
}

fun main(args: Array<String>) {
    var test = Test()

    /**
     * 采用对象表达式来创建接口对象,即匿名内部类的实例。
     */
    test.setInterFace(object : TestInterFace {
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })
}

11. 扩展函数(类似java中的装饰者设计模式)

// 扩展函数 swap,调换不同位置的值
fun MutableList<Int>.swap(index1: Int, index2: Int) {
    val tmp = this[index1]     //  this 对应该列表,注意是对应脚标位置的值进行的替换
    this[index1] = this[index2]
    this[index2] = tmp
}
fun main(args: Array<String>) {
    val l = mutableListOf(1, 2, 3)
    // 位置 0 和 2 的值做了互换,!!!
    l.swap(0, 2) // 'swap()' 函数内的 'this' 将指向 'l' 的值
    println(l.toString())
}
实例执行输出结果为:
[3, 2, 1]

12. 扩展函数和成员函数一致,优先使用成员函数

class C {
    fun foo() { println("成员函数") }
}

fun C.foo() { println("扩展函数") }

fun main(arg:Array<String>){
    var c = C()
    c.foo()
}

实例执行输出结果为:
成员函数

13. 扩展函数是静态解析的
在调用扩展函数时,具体被调用的的是哪一个函数,由调用函数的的对象表达式来决定的,而不是动态的类型决定的(这样说来其实感觉kotlin很无脑,给他指定是谁就是谁,不会由调用者来动态的决定)

open class C
class D: C()
fun C.foo() = "c"   // 扩展函数 foo
fun D.foo() = "d"   // 扩展函数 foo
fun printFoo(c: C) {
    println(c.foo())  // 类型是 C 类
}
fun main(arg:Array<String>){
    printFoo(D())
}
实例执行输出结果为:
c

14. 扩展属性
除了函数,Kotlin 也支持属性对属性进行扩展:

val <T> List<T>.lastIndex: Int
    get() = size - 1

扩展属性允许定义在类或者kotlin文件中,不允许定义在函数中。初始化属性因为属性没有后端字段(backing field),所以不允许被初始化,只能由显式提供的 getter/setter 定义。
val Foo.bar = 1 // 错误:扩展属性不能有初始化器
扩展属性只能被声明为 val。

15. 在一个类内部你可以为另一个类声明扩展。

class D {
    fun bar() { println("D bar") }
}
class C {
    fun baz() { println("C baz") }
    fun D.foo() {
        bar()   // 调用 D.bar
        baz()   // 调用 C.baz
    }
    fun caller(d: D) {
        d.foo()   // 调用扩展函数
    }
}
fun main(args: Array<String>) {
    val c: C = C()
    val d: D = D()
    c.caller(d)
}
实例执行输出结果为:
D bar
C baz
//在 C 类内,创建了 D 类的扩展。此时,C 被成为分发接受者,而 D 为扩展接受者。从上例中,可以清楚的看到,在扩展函数中,可以调用派发接收者的成员函数。

16. 分发接收者虚拟解析,扩展接收者静态解析
以成员的形式定义的扩展函数, 可以声明为 open , 而且可以在子类中覆盖. 也就是说, 在这类扩展函数的派 发过程中, 针对分发接受者是虚拟的(virtual), 但针对扩展接受者仍然是静态的。

open class D {
}
class D1 : D() { //1.扩展接收者
}
open class C { //2. 分发接收者
    open fun D.foo() {
        println("D.foo in C")
    }
    open fun D1.foo() {
        println("D1.foo in C")
    }
    fun caller(d: D) {
        d.foo()   // 调用扩展函数
    }
}
class C1 : C() {
    override fun D.foo() {
        println("D.foo in C1")
    }

    override fun D1.foo() {
        println("D1.foo in C1")
    }
}
fun main(args: Array<String>) {
    C().caller(D())   // 输出 "D.foo in C"
    C1().caller(D())  // 输出 "D.foo in C1" —— 分发接收者虚拟解析
    C().caller(D1())  //为什么不是输出 D1.foo in C ? 实际输出D.foo in C —— 扩展接收者静态解析
    C1().caller(D1())  //为什么不是输出 D1.foo in C1?实际输出 D.foo in C1
}
实例执行输出结果为:
D.foo in C
D.foo in C1
D.foo in C

17.外部类扩展函数为优先级最高

class MyClass {
    companion object {
        val myClassField1: Int = 1
        var myClassField2 = "this is myClassField2"
        fun companionFun1() {
            println("this is 1st companion function.")
            foo()
        }
        fun companionFun2() {
            println("this is 2st companion function.")
            companionFun1()
        }
    }
    fun MyClass.Companion.foo() { //这个方法是有误的,给本类添加伴随扩展函数不就是自己的函数吗?在调用的时候会以外部扩展函数优先
        println("伴随对象的扩展函数(内部)")
    }
    fun test2() {
        MyClass.foo()
    }
    init {
        test2()
    }
}

val MyClass.Companion.no: Int
    get() = 10
fun MyClass.Companion.foo() {
    println("foo 伴随对象外部扩展函数")
}

fun main(args: Array<String>) {
    println("no:${MyClass.no}")  //输出 10
    println("field1:${MyClass.myClassField1}") //输出 1
    println("field2:${MyClass.myClassField2}") //输出this is myClassField2
    MyClass.foo() //输出 伴随对象的扩展函数(内部)---错了
    MyClass.companionFun2() //输出 this is 2st companion function. this is 1st companion function foo 伴随对象外部扩展函数
}

输出结果
no:10
field1:1
field2:this is myClassField2
foo 伴随对象外部扩展函数
this is 2st companion function.
this is 1st companion function.
foo 伴随对象外部扩展函数

18.泛型

fun main(args: Array<String>) {
    val age = 23
    val name = "runoob"
    val bool = true

    doPrintln(age)    // 整型
    doPrintln(name)   // 字符串
    doPrintln(bool)   // 布尔型
}

fun <T> doPrintln(content: T) {

    when (content) {
        is Int -> println("整型数字为 $content")
        is String -> println("字符串转换为大写:${content.toUpperCase()}")
        else -> println("T 不是整型,也不是字符串")
    }
}
输出结果为:
整型数字为 23
字符串转换为大写:RUNOOB
T 不是整型,也不是字符串

19. out使得类型参数协变,in使得类型参数逆变
out----协变类型参数用作输出,可以用作返回值但是无法作为入参的类型
in------逆变类型参数只能用作入参的类型,不能作为返回值(编译时期报错)

// 定义一个支持协变的类
class Runoob<out A>(val a: A) {
    fun foo(): A {
        return a
    }
}
fun main(args: Array<String>) {
    var strCo: Runoob<String> = Runoob("a")
    var anyCo: Runoob<Any> = Runoob<Any>("b")
    anyCo = strCo
    println(anyCo.foo())   // 输出 a
}
// 定义一个支持逆变的类
class Runoob<in A>(a: A) {
    fun foo(a: A) {
    //此处添加返回值,在编译期就会报错
    }
}
fun main(args: Array<String>) {
    var strDCo = Runoob("a")
    var anyDCo = Runoob<Any>("b")
    strDCo = anyDCo
}

20. 枚举

enum class Color{
    RED,BLACK,BLUE,GREEN,WHITE
}

fun main(args: Array<String>) {
    var color:Color=Color.BLUE

    println(Color.values())
    println(Color.valueOf("RED")) // 转换指定 name 为枚举值,若未匹配成功,会抛出IllegalArgumentException
    println(color.name)
    println(color.ordinal)
}

自 Kotlin 1.1 起,可以使用 enumValues<T>() 和 enumValueOf<T>() 函数以泛型的方式访问枚举类中的常量 :

enum class RGB { RED, GREEN, BLUE }

inline fun <reified T : Enum<T>> printAllValues() {
    print(enumValues<T>().joinToString { it.name })
}

fun main(args: Array<String>) {
    printAllValues<RGB>() // 输出 RED, GREEN, BLUE
}

21.匿名对象的公有函数类型的成员返回的是any不能进行访问

class C {
    // 私有函数,所以其返回类型是匿名对象类型
    private fun foo() = object {
        val x: String = "x"
    }
    // 公有函数,所以其返回类型是 Any
    fun publicFoo() = object {
        val x: String = "x"
    }
    fun bar() {
        val x1 = foo().x        // 没问题
        val x2 = publicFoo().x  // 错误:未能解析的引用“x”
    }
}

22.定义一个被委托的类
该类需要包含 getValue() 方法和 setValue() 方法,且参数 thisRef 为进行委托的类的对象,prop 为进行委托的属性的对象

import kotlin.reflect.KProperty
// 定义包含属性委托的类
class Example {
    var p: String by Delegate()
}
// 委托的类
class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, 这里委托了 ${property.name} 属性"
    }
    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$thisRef${property.name} 属性赋值为 $value")
    }
}
fun main(args: Array<String>) {
    val e = Example()
    println(e.p)     // 访问该属性,调用 getValue() 函数

    e.p = "Runoob"   // 调用 setValue() 函数
    println(e.p)
}
输出结果为:
Example@433c675d, 这里委托了 p 属性
Example@433c675d 的 p 属性赋值为 Runoob
Example@433c675d, 这里委托了 p 属性

23.委托----Lazy延迟属性

val lazyValue: String by lazy {
    println("computed!")     // 第一次调用输出,第二次调用不执行
    "Hello"
}

fun main(args: Array<String>) {
    println(lazyValue)   // 第一次执行,执行两次输出表达式
    println(lazyValue)   // 第二次执行,只输出返回值
}

执行输出结果:

computed!
Hello
Hello

24.委托—observable(观察者设计模式)

import kotlin.properties.Delegates
class User {
    var name: String by Delegates.observable("初始值") {
        prop, old, new ->
        println("旧值:$old -> 新值:$new")
    }
}
fun main(args: Array<String>) {
    val user = User()
    user.name = "第一次赋值"
    user.name = "第二次赋值"
}
执行输出结果:
旧值:初始值 -> 新值:第一次赋值
旧值:第一次赋值 -> 新值:第二次赋值

25. 委托模式

import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class ResourceID() {
    val image_id: String = "101"
    val text_id: String = "102"
}
class ResourceLoader(id: ResourceID) {
    val d: ResourceID = id
    operator fun provideDelegate( thisRef: MyUI, prop: KProperty<*>): ReadOnlyProperty<MyUI, String> {
        if(checkProperty(thisRef, prop.name)){
            return DellImpl(d)
        }else{
            throw Exception("Error ${prop.name}")
        }
    }
    private fun checkProperty(thisRef: MyUI, name: String):Boolean {
        return name.equals("image") || name.equals("text")
    }
}
class DellImpl(d: ResourceID) : ReadOnlyProperty<MyUI, String> {
    val id: ResourceID = d
    override fun getValue(thisRef: MyUI, property: KProperty<*>): String {
        if(property.name.equals("image"))
            return property.name+"  "+id.image_id
        else
            return property.name+"  "+id.text_id
    }
}
fun  bindResource(id: ResourceID): ResourceLoader {
    var res = ResourceLoader(id);
    return res
}
class MyUI {
    val image by bindResource(ResourceID())
    val text by bindResource(ResourceID())
    //val webview by bindResource(ResourceID())
}
fun main(args: Array<String>) {
    try{
        var ui = MyUI()
        println(ui.image)
        println(ui.text)
    }catch(e: Exception) {
        println(e.message)
    }
}
// 输出
/**
 * image  101
 * text  102
 */
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. Android Studio是什么? Android Studio是一个由Google开发的集成开发环境(IDE),用于开发Android应用程序。 2. Android Studio的特点是什么? Android Studio具有以下特点: - 提供了丰富的工具和功能,使开发人员能够更轻松地创建高质量的Android应用程序。 - 集成了Android SDK,可以轻松地管理应用程序的构建、测试和部署。 - 支持多种编程语言,包括Java、Kotlin和C++。 - 提供了强大的调试和分析工具,帮助开发人员快速解决问题。 - 支持多种设备和屏幕尺寸,可以轻松地创建适用于不同设备的应用程序。 3. Android Studio的安装步骤是什么? Android Studio的安装步骤如下: - 下载Android Studio安装包。 - 运行安装程序,按照提示进行安装。 - 安装完成后,启动Android Studio,并按照提示进行配置。 4. Android Studio中的Gradle是什么? Gradle是一种构建工具,用于构建Android应用程序。在Android Studio中,Gradle用于管理应用程序的依赖关系、编译代码、打包应用程序等。 5. Android Studio中的布局编辑器是什么? 布局编辑器是Android Studio中的一个工具,用于创建和编辑Android应用程序的用户界面。开发人员可以使用布局编辑器轻松地创建各种布局,包括线性布局、相对布局、表格布局等。 6. Android Studio中的调试工具是什么? Android Studio中的调试工具包括调试器、日志记录器、监视器等。开发人员可以使用这些工具来调试应用程序,查找和解决问题。 7. Android Studio中的版本控制是什么? 版本控制是一种管理代码版本的工具,可以帮助开发人员更好地管理代码。在Android Studio中,开发人员可以使用Git等版本控制工具来管理代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值