kotlin的一些学习和使用时遇到的问题

qq_33667176 · · 271 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

前段时间学习了一下kotlin,主要是通过这本书来学习的,这个是中文版下载地址:
(https://github.com/wangjiegulu/kotlin-for-android-developers-zh)
这个网站是一个可以测试kotlin代码的,对学习kotlin也是挺有帮助的。
(https://try.kotlinlang.org)
也看了看这个,了解一下kotlin的常用语法等。
(http://kotlinlang.org/docs/reference)

然后也自己做了一个小项目感受了一下,感觉这门语言还是很ok的,写起来确实简单,目前没发现什么大问题,有一个小问题就是 android studio 有时候好像不识别ArrayList 和 MutableList的转换 经常会报错,只要删除在重新粘贴上去就可以了。

下面来记录一下自己使用的遇到的坑。。。

1.Extension(扩展函数)

这个东西大概是最早没接触的时候就一直在听大家在那里吹捧了,说是可以代替utils类啊什么的。
定义这个方法:Object.MethodName : returnType
Object是你要将这个扩展函数定义在哪个类下面,比如你要定义一个Activity的扩展函数就可以使用Activity.
MethodName就是方法名字啦
returnType是返回值类型,kotlin的默认返回类型不是void,而是一个Unit类型,对应java中的void类型。

使用这个的时候需要注意,需要把扩展函数定义为包级函数(就是新建一个kt文件里面不写class,直接写fun就行),如果写到类里面就只能在当前那个类里调用这个方法了。举个例子:

//一个Context扩展函数,获取屏幕高度。
fun Context.getScrennHeight(): Int {
//kotlin使用var的方式来声明变量,:后面跟的是变量的类型
//this@区分你要使用哪个类的this
//as关键字用来将对象转换到对应的类型
    var wm: WindowManager = this@getScrennHeight.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    return wm.defaultDisplay.height
}

//我们在activity中就可以直接调用这个方法,就像这样:
    class Activity1 : Activity(){
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            //调用我们的extension
            getScreenWidth()
        }
    }

2.companion object(伴生对象)

kotlin中没有static方法,所以如果我们想要使用像java中的静态方法的调用,好像也没法实现静态代码块了,不过可以写在companion object块中也可以接受吧。在companion object块中定义的函数或者是对象可以直接通过类名.来调用。kotlin没有构造方法 但是 有一个init块,在实例化的时候会调用这个init块,有点仿照jvm的实现。

class Test1{
    init {
        //实例化时调用
    }

    companion object{
        //这个块里面的可以直接通过类名.调用
    }
}

3.inline fun(内联函数)

见名知意,就是一个函数接收一个函数作为参数,内联函数会在编译的时候被替换掉,而不是真正调用这个方法,可以减少我们的内存分配和运行时开销,举个例子吧:

    inline fun inline1(code : () -> Unit){
        //code是我们自己定义的方法名字 -> 后面是返回值
        //这里可以写一些判断条件,比如我们android经常要判断sdk版本来执行不同的方法
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) code()
    }

    fun invokeInline1(){
        inline1{
            //调用内联函数inline1
            //当条件满足才会执行code()
        }
    }

这样我们在编译的时候code()会被替换掉,而不是调用code(),就不需要为code()生成一个的对象。

4.with函数

这个函数在adapter中简直不要太好用,api中的定义是这样的

@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

接收一个T类型对象和一个T中的方法作为参数,并且这个T中的方法的返回值是R类型,最后返回结果也是R类型,这个就是相当于是返回第二个参数作为返回结果了嘛。所以,我们在adapter写出来就像这样:

//声明我们的data类,data类也是kotlin中特有的一个扩展,可以帮我们自动生成get set方法,不需要写实现,我们只需要定义类就可以了
data class PhotoData(var name:String)
...
//MutableList是kotlin增强版的Arraylist 支持各种过滤操作符
var mData : MutableList<PhotoData> = ArrayList()
...
//这个是在bindview中使用我们的with函数
with(mData[position]){
    // holder为adapter中的ViewHolder对象
    // ?.就相当于java中的 if null else
    //image假设是我们的控件,text=setText
    //我们就可以直接调用我们PhotoData中的变量,而不用在通过.的方式来调用了
    holder?.itemview.image.text = name  
}

5.匿名内部类的写法

这个是刚开始用的时候遇到的一个坑,kotlin本身是支持lambda的,比如我们写一个onClick事件的时候就可以直接这样写:

view.setOnClickListener {
               //直接在这里写操作
}

但是如果我们要是想将它写全的话就得这么写:

                view.setOnClickListener(object : View.OnClickListener{
                    override fun onClick(v: View?) {
                        TODO("not implemented") 
                    }
                })

使用object关键字:后面就是它的值类型

其实还有好多小特性

比如if else 可以使用=号啊

anko库可以直接支持我们在activity中直接使用xml中的id来对控件直接进行操作而不用find了(fragment中还得find。。)

声明变量时如果不带?出现null的情况编译不会通过

方法体如果直接一行,返回值可以直接用等号表示

请求网络可以直接使用URL(url).readText()

asynctask使用直接可以用 doAsync{}快来表示

Class类型的表示方式:Test::class.java

java中Test.class的表示方式在kotlin是应该这样写Test().javaclass

使用lazy委托来实现延迟加载(kotlin中声明变量必须要赋值)

by map 使用map委托来声明map

创建list可以使用:listOf()

声明普通数组使用: Array<T>

interface中可以直接写方法实现,这个是java8才支持的

简单的EL表达式也是可以使用

is关键字:a is b 表示a是否属于b类型

out参数修饰符:协变(convariance),表示该参数只能作为返回值而不能作为传入参数

in参数修饰符:逆变(contravariance),表示该参数只能作为传入值,不能作为返回值

to关键字,,返回一个Pair对象

等等。。。

本文来自:CSDN博客

感谢作者:qq_33667176

查看原文:kotlin的一些学习和使用时遇到的问题

271 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet