【Kotlin】遇见的问题记录

一:常见语法糖【https://www.runoob.com/kotlin/kotlin-tutorial.html

1.【安卓】import android.R

R.id.myTextView1是指向布局中的空间TextView,

这个Textview的id被设置成了"@+id/myTextView1",你到layout文件夹下找main.layout就能看到它。

并且不使用import android.R  若果使用的话R.id就会去R包下面去找,报错

import java.util.TreeMap

fun main(args: Array<String>) {
    var a="zero"
    val b:Long=1231
    //类型转换
    var l=12
    var m="12"
    l=m.toInt()
    m=l.toString()
    println(a)
    println(b)
    sayHello()
    println(diary("panada"))
    println(getmess(null))
    var nums=1..10//声明数组区间
    for(num in nums)
        print(num)
    //list 的引用
    var lists= listOf("1","2",3)
//    for(list in lists)
//        print(list)
//有序列
    for((i,e)in lists.withIndex()) {
        println("$i $e")
    }

    //map运用 类似词典 且有索引
    var map=TreeMap<String,String>()
    map["好"]="good"
    map["学"]="study"
    map["向上"]="up"
     println(map["好"])
    print(z(3,5))
    //ps调用float单精度area(3.0f,3.0f)
}
//函数
fun sayHello(){
    println("Hello")
}
//无参数无返回类型
//fun sum(a: Int, b: Int): Int=x+y
fun sum(a: Int, b: Int): Int {   // Int 参数,返回值 Int
    return a + b
}

var z={x:Int,y:Int -> x+y}
var y:(Int,Int)->Int={x,y ->x+y}
//print包裹dollar参数取值
fun diary(place:String):String{
    var message="你好${place}"
    return message
}
//排除空指针异常+?表示传入可为“null”
fun getmess(mess:String?):String{
    return "得到"+mess
}
//switch与when语句
fun grade(score:Int){
    when(score){
        10-> print("考了满分")
        8-> print("考的不错")
        else-> print("继续加油")
    }
}

2.5数组在 Kotlin 中使用 Array 类来表示,它定义了 get 与 set 函数(按照运算符重载约定这会转变为 [])以及 size 属性,以及一些其他有用的成员函数:

class Array<T> private constructor() {

    val size: Int

    operator fun get(index: Int): T

    operator fun set(index: Int, value: T): Unit

    operator fun iterator(): Iterator<T>

    // ……

}

为了获得更好的效率,Kotlin提供了原生类型数组:ByteArray、 ShortArrayIntArray 等,不需要装箱开销,它们和Array没有继承关系,但又同样的方法属性,也有相应的工厂方法。

val x: IntArray = intArrayOf(1, 2, 3)

x[0] = x[1] + x[2]

// 大小为 5、值为 [0, 0, 0, 0, 0] 的整型数组

val arr = IntArray(5)

// 例如:用常量初始化数组中的值

// 大小为 5、值为 [42, 42, 42, 42, 42] 的整型数组

val arr = IntArray(5) { 42 }

int max=(a>b)?a:b;

if不只是条件语句,它还是表达式,因此Kotlin没有c的三元运算符,它可以用if表达式取代:

val max = if (a > b) a else b

二:输入输出

fun main(args: Array<String>){
    while (true){


    println("请输入第一个数字")
    var num1= readLine()
    println("请输入第二个数字")
    var num2= readLine()
//35字符串连接
/*    var num3=num1?.toInt()
    var num4=num1?.toInt()
    println("${num3}+${num4}=${num3+num4}")*/
//?输入为空则空,但空和空无法相加会报错 !!抛出空指针异常
    //更新输入a抛出异常,结合while就可以一直运行,不报运行代码错误
    try {
    var num3:Int=num1!!.toInt()
    var num4:Int=num2!!.toInt()
    println("${num3}+${num4}=${num3+num4}")
    }catch (e:Exception){
        println("大哥,你输入的有问题吧 ")
    }
}
}

三.方法与调用

class Girl(var chactor:String,var voice:String){//静态构造
    //两个动态方法
    fun smile(){
        println("妹子笑了一下,么么哒")
    }

    fun cry(){
        println("呜呜呜,人家伤心")
    }
}

fun main(args: Array<String>){
    var girl1=Girl(chactor = "温柔",voice = "甜美")
    print("girl1这位妹子的声音:${girl1.voice}")
    girl1.cry()
    girl1.smile()

}
import javax.swing.tree.FixedHeightLayoutCache
//矩形类与复合类型
class Rect(var height:Int,var width:Int)

fun main(args: Array<String>){
    var rect1=Rect(height = 10,width = 20)
    print("矩形的高度:${rect1.height}")
}

ps:用when替代switch

一.起因//主构造函数的属性可以会成为内部类的属性

  1. Kotlin类的构造函数名是constructor(符合一定条件,主构造函数名可以省略),而不是类名
  2. Kotlin类的主构造函数的参数自动成为类的成员属性
  3. Kotlin没有static关键字,因此不存在静态成员,伴生对象成员可以起到静态成员的作用

用这种构造方法报错了:supertype initiallzation is impossible without primary constructor

分析一下:没有主构造函数,就不可能进行超类型的初始化

class LocalMusicAdapter: RecyclerView.Adapter<LocalMusicAdapter.LocalMusicViewHolder>() {

    //传入数据源
    var context: Context?=null
    var mDatas: List<LocalMusicBean>? = null
    //创建构造方法
    constructor(context: Context?, mDatas: List<LocalMusicBean>?)  {
        this.context = context
        this.mDatas = mDatas
    }

 //   fun LocalMusicAdapter(context: Context, mDatas: List<LocalMusicBean>) {
 //        this.context = context
 //       this.mDatas = mDatas
 //   }

默认情况下:主构造函数可以是无参构造函数  

和次级构造函数的区别标志在于他写在类名后面

拓展:有主构造函数和无的区别

关于无参构造函数:

创建一个子类对象的实例的时候,必先调用父类的无参构造函数(默认构造函数),假如父类有带参数的构造函数,那么系统不会给他创建无参数的构造函数,这时,子类在实例化的时候,因为找不到父类的默认构造函数,编译器会报错,如果在子类的构造函数中指定使用父类的带参数的构造函数的时候,或者在父类中加一个无参数的构造函数的时候,就不会报错了。

二.文档

//没有static静态成员-》伴生对象

//原生数组与Array泛型取代数组

三.关于kotlin与空指针异常【https://www.jianshu.com/p/51b2e5aa3dd8

这是因为编译器在转化时为了保证代码转化前后的一致性所造成的。换句话说,在Java上出异常的,转化到KT上,编译器任然会让他保持抛出异常,NullPointerException也是如此。

所以结合上下文可以看得出,!!加上去后好像并没有和之前Java代码有什么区别嘛,该null的地方任然会抛出异常。所以大多数情况下都会使用?来检测null,轮不到!!出场。!!只会在你需要对某对象进行非空判断,并且需要抛出异常时才会使用到。

即翻译时的逻辑一制性。

类型转换,如果不成功可能会导致 ClassCastException

可以使用as?操作符,不成功则返回null

val aInt: Int? = a as? Int

选择->音乐->额外存储

四.构造器,主构造方法,次级构造方法

//典型画蛇添足样例

五.错误实例【java型kotlin编码】

package com.ywjh.localfaraway

import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

import android.view.View
import android.widget.TextView

import android.view.LayoutInflater






class LocalMusicAdapter(): RecyclerView.Adapter<LocalMusicAdapter.LocalMusicViewHolder>() {

    //传入数据源
    var context: Context?=null
    var mDatas: MutableList<LocalMusicBean>? = null
    //创建构造方法



    constructor(context: Context?, mDatas: MutableList<LocalMusicBean>?) : this() {
        this.context = context
        this.mDatas = mDatas
    }



//    fun LocalMusicAdapter(context: Context, mDatas: List<LocalMusicBean>) {
//        this.context = context
//        this.mDatas = mDatas
//    }

    //创建并返回 ViewHolder 生成与初始化
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocalMusicViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.item_local_music, parent, false)
        val holder = LocalMusicViewHolder(view)
        return holder
    }
    //返回条目数量
    override fun getItemCount(): Int {
        return mDatas!!.size
    }
    //绑定Viewholder 拿到holser后对TextView进行设置
    override fun onBindViewHolder(holder: LocalMusicViewHolder, position: Int) {
        val musicBean = mDatas?.get(position)
        holder.idTv?.setText(musicBean!!.getId())
        holder.songTv?.setText(musicBean!!.getSong())
        holder.singerTv?.setText(musicBean!!.getSinger())
        holder.albumTv?.setText(musicBean!!.getAlbum())
        holder.timeTv?.setText(musicBean!!.getDuration())

        //holder.itemView.setOnClickListener { v -> onItemClickListener.OnItemClick(v, position) }
    }


    class LocalMusicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        //继承recycleView和ViewHolder内部类
        var idTv: TextView? = null
        var songTv:TextView? = null
        var singerTv:TextView? = null
        var albumTv:TextView? = null
        var timeTv:TextView? = null

        public fun LocalMusicViewHolder(itemView: View) {//kotlin 当中没有这种构造方法,所有不会进行初始化

            idTv = itemView.findViewById(R.id.item_local_music_num)
            songTv = itemView.findViewById(R.id.item_local_music_song)
            singerTv = itemView.findViewById(R.id.item_local_music_singer)
            albumTv = itemView.findViewById(R.id.item_local_music_album)
            timeTv = itemView.findViewById(R.id.item_local_music_durtion)

        }



    }
}

更改后

1.原本理解不够,写的特别有问题,【LocalMusicAdapter】kotlin的主构造方法传入两个参数,var一下之后 内部就可以直接用【就相当于构造方法初始化过了】

2.【 LocalMusicViewHolder】有主构造方法传个View,接着使用init方法自动初始化就好了

3.借鉴了这位大佬的帖子,里面还有伴生对象的说明【https://blog.csdn.net/yuzhiqiang_1993/article/details/87863589

package com.ywjh.localfaraway

import android.content.Context

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.ywjh.localfaraway.LocalMusicBean

class LocalMusicAdapter(internal var context: Context, internal var mDatas: List<LocalMusicBean>) :
    RecyclerView.Adapter<LocalMusicAdapter.LocalMusicViewHolder>() {



    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocalMusicViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.item_local_music, parent, false)
        //ps  val holder = LocalMusicViewHolder(view)
        //        return holder
        return LocalMusicViewHolder(view)
    }

    override fun onBindViewHolder(holder: LocalMusicViewHolder, position: Int) {
        val musicBean = mDatas[position]
        holder.idTv.setText(musicBean.getId())
        holder.songTv.setText(musicBean.getSong())
        holder.singerTv.setText(musicBean.getSinger())
        holder.albumTv.setText(musicBean.getAlbum())
        holder.timeTv.setText(musicBean.getDuration())


    }

    override fun getItemCount(): Int {
        return mDatas.size
    }

    inner class LocalMusicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var idTv: TextView
        var songTv: TextView
        var singerTv: TextView
        var albumTv: TextView
        var timeTv: TextView

        init {
            idTv = itemView.findViewById(R.id.item_local_music_num)
            songTv = itemView.findViewById(R.id.item_local_music_song)
            singerTv = itemView.findViewById(R.id.item_local_music_singer)
            albumTv = itemView.findViewById(R.id.item_local_music_album)
            timeTv = itemView.findViewById(R.id.item_local_music_durtion)
        }
    }
}

六.惰性加载

在使用kotlin开发中,因为各种原因,我们会经常需要使用到延迟加载的功能,目前kotlin的延迟加载主要有两种:lateinitlazy

var之前添加lateinit  val使用lazy【https://blog.csdn.net/liyi1009365545/article/details/84236433

七.伴生对象

在Java中可以通过static关键字声明静态的属性或方法。但是在Kotlin中并没有延用这个关键字,而是使用伴生对象实现,在class内部声明一个companion object代码块,其内部的成员变量和方法都将被编译成为静态的。【https://www.jianshu.com/p/ac0c25091491

其与匿名内部类的区别(companion object代码块中的成员变量最终会被声明到外部类中,也这是为什么我们能通过外部类名直接访问,而object类则需要用外部类.内部类的方式调用。)

八.接口

java中若接口的方法只有一个,可以直接省去实现接口参数,直接复写方法就好了

发布了27 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_38304672/article/details/104371128