免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

Kotlin使用高階函數(shù)實現(xiàn)回調(diào)方式

lambda 和 高階函數(shù)

碾子山網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,碾子山網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為碾子山成百上千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的碾子山做網(wǎng)站的公司定做!

之前學習了 lambda 和高階函數(shù),然后在 android 開發(fā)中對 onClick 事件進行監(jiān)聽是一個很常用的功能,kotlin 的常規(guī)實現(xiàn)如下:

  rootView.setOnClickListener { view ->
    println("點擊了這個ID=${view.id}的view")
  }

然后在開發(fā)中不可避免的我們也要寫一些自定義監(jiān)聽之類的代碼。這個時候如果還用 java 的思想去實現(xiàn)的話就有點舍近求遠了。

java 思想實現(xiàn)

在 java 中我們一般的做法是這樣的

定義一個接口
定義一個接口類型變量
定義一個 set 方法
調(diào)用 set 方法設(shè)置接口的實現(xiàn)類

用 kotlin 實現(xiàn)就是如下

class MyView{
  //定義一個接口
  interface IOnLabelCheckedListener {
    fun onLabelCheck(label: String)
  }
  //定義一個接口類型變量
  private var onLabelChecked: IOnLabelCheckedListener? = null

  private fun initView(context: Context) {
    view.setOnCheckedChangeListener { radioGroup, i ->
        onLabelChecked.onLabelCheck(radioGroup.findViewById<RadioButton>(i).text.toString())
    }
  }
  //定義一個 set 方法
  fun setOnLabelCheckedListener(e: IOnLabelCheckedListener) {
    this.onLabelChecked = e
  }
}

   // 調(diào)用set方法,通過匿名內(nèi)部類實現(xiàn)
    MyView.setOnLabelCheckedListener(object : LabelBarView.IOnLabelCheckedListener {
      override fun onLabelCheck(label: String) {

      }
    })

這樣實現(xiàn)的問題

當然是太復(fù)雜了。而且最初的時候這樣寫一時搞不明白為什么 MyView.setOnLabelCheckedListener 方法內(nèi)部不能傳入 lambda 表達式,lambda 表達式的存在不就是為了替代匿名內(nèi)部類嘛。而且如果這個接口定義的是一個 java 類型的接口就是可以用 lambda 表達式的。這是為什么?最后猜想是因為 kotlin 在和 java 互相調(diào)用的時候中間又包裹了一層,而我們直接使用 kotlin 來定義這個接口不存在中間這一層,而我們定義的 set 方法又不是一個高階函數(shù),當然不能使用 lambda 表達式。

下面就用 kotlin 的思想來實現(xiàn)回調(diào)

使用高階函數(shù)來實現(xiàn)

kotlin 和 java 有一個重要的不同就是函數(shù)式編程。在函數(shù)式編程的思想中函數(shù)是一等公民,在使用 kotlin 時我們要多利用這種思維來思考問題。Kotlin 中提供了高階函數(shù),它可以直接使用一個函數(shù)來作為返回值,對于習慣于 java 來編程的我來說剛開始理解起來有些困難,下面我把我一步一步的實現(xiàn)一個高階函數(shù)的思路寫下,希望對大家有所幫助。

首先,能想到的就是函數(shù)傳遞,要用 lambda 來替代掉匿名內(nèi)部類可以這樣來實現(xiàn)

//從最基礎(chǔ)的開始做,把匿名內(nèi)部類通過 lambda 實現(xiàn)
MyView.setOnLabelCheckedListener(object : MyView.IOnLabelCheckedListener {
    override fun onLabelCheck(label: String) {
     println(label)
    }
})
// 首先 MyView.IOnLabelCheckedListener 中只有一個方法 onLabelCheck(label: String)
// 因此可以寫出 lambda 表達式如下
var lam: (String) -> Unit = { label -> println(label) }

然后,需要把寫好的 lambda 傳遞進去,這個時候就要求 setOnLabelCheckedListener 方法是一個高階函數(shù)

  // 這里接收一個 上面我們改造好的表達式 lam ,它內(nèi)部實現(xiàn)應(yīng)該是把 e 賦值給當前類的一個對象
  fun setOnLabelCheckedListener(e: (String) -> Unit) {
    this.lisenter = e
  }
 
  //顯然 lisenter 就應(yīng)該是這樣的
  var linsnter: (String) -> Unit = {}

最后使用 linsnter 進行回調(diào)

  private fun initView(context: Context) {
    view.setOnCheckedChangeListener { radioGroup, i ->
      linsnter(radioGroup.findViewById<RadioButton>(i).text.toString())
    }
  }

最終代碼結(jié)果:

class MyView{
  var linsnter: (String) -> Unit = {}

 private fun initView(context: Context) {
    view.setOnCheckedChangeListener { radioGroup, i ->
      linsnter(radioGroup.findViewById<RadioButton>(i).text.toString())
    }
 }

 fun setOnLabelCheckedListener(e: (String) -> Unit) { 
  this.lisenter = e
 }
}
  // 調(diào)用時將變量 lam 省略,直接使用一個表達式
  view.setOnLabelCheckedListener { label ->
    println(label)
  }

最終的代碼和之前的代碼有兩個最大的不同,一是沒有了接口定義,二是沒有了匿名內(nèi)部類。

更好的使用高階函數(shù)

高階函數(shù)的使用更多的時候能使我們的代碼更簡潔,比如下面這段代碼:

  fun refreshData(e: ((Boolean, String) -> Unit)): Boolean {

    if (!UserInfoManager.getInstance().isLogin) {
      e(false, "未登錄")
      return false
    }

    NETWorkUtils.request(ApiParamter(), object : ApiListener<ResponseData> {
      override fun onApiCompleted(data: ResponseData?) {
          e(true, "成功")
      }

      override fun onApiError(errorCode: Int, errorCodeMessage: String) {
         e(false, errorCodeMessage)
      }
    })
    return true
  }

那么在調(diào)用它的時候就可以這樣:

   mView.refreshData { isSuccess, msg ->
      //do something
  }

是不是很簡單,省去了再寫一個接口。同時如果是用 java 來調(diào)用 refreshData 方法也一樣可以的:

    mView.refreshData(new Function2<Boolean, String, Unit>() {
      @Override
      public Unit invoke(Boolean aBoolean, String s) {
        // do something
        return null;
      }
    });

Kotlin 提供了一系列的 Function 接口類來供 java 調(diào)用高階函數(shù)時使用,最多支持22個參數(shù)有興趣的可以查看一下。

以上就是在 Kotlin 中使用高階函數(shù)來替代傳統(tǒng)的回調(diào)函數(shù)的方法。不對之處還請指正。希望能給大家一個參考,也希望大家多多支持創(chuàng)新互聯(lián)。

當前標題:Kotlin使用高階函數(shù)實現(xiàn)回調(diào)方式
文章位置:http://m.newbst.com/article26/pepccg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站Google手機網(wǎng)站建設(shè)關(guān)鍵詞優(yōu)化小程序開發(fā)移動網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司