首页 > 解决方案 > Kotlin 语法混淆:使用 lambda 传递接口

问题描述

我正在研究 Android 的 Kotlin 编程,我试图深入理解这段代码(有效)。它来自网络请求的 Volley 库:

//Network stuff
    // Request a string response from the provided URL.
    val jsonObjectRequest = object : JsonObjectRequest(Method.POST, http, ob,
            Response.Listener<JSONObject> { response ->
                // Display the first 500 characters of the response string.
                Log.d("Debug","Response is: ${response.toString()} ")

            },
            Response.ErrorListener { error ->
                Log.d("Debug","That didn't work! Code: ${error.message}")
            })
    {
        @Throws(AuthFailureError::class)
            override fun getHeaders(): Map<String, String> {
                val headers = HashMap<String, String>()
                headers.put("Content-Type", "application/json")
                headers.put("Accept", "application/json")
                return headers
        }

    }

我的问题是关于第一个块,就在JsonObjectRequest对象的构造函数内。我知道对象构造、lambda、类和接口,但有一点我没有在这里得到。此外,我已经在 Kotlin 中看到了这个线程 Pass 接口作为参数

我的问题是:用于构造的第四个参数发生了JsonObjectRequest什么?据我所见,有一个 lambda 覆盖了一些相关的函数,Response.Listener<JSONObject>但我没有找到对该语法的任何引用。

总而言之,objectRequest 具有前一个构造函数:

    public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
        Listener<JSONObject> listener, ErrorListener errorListener) {
    super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
                errorListener);
}

并且侦听器具有以下部分:

public class Response<T> {

/** Callback interface for delivering parsed responses. */
public interface Listener<T> {
    /** Called when a response is received. */
    void onResponse(T response);
}

/** Callback interface for delivering error responses. */
public interface ErrorListener {
    /**
     * Callback method that an error has been occurred with the
     * provided error code and optional user-readable message.
     */
    void onErrorResponse(VolleyError error);
}

读到这里,我知道我们正在使用这种语法实现 Listener 接口,但我不明白为什么我们使用 lambda,因为在 Listener 中没有对它的引用,特别是这意味着什么:

 Response.Listener<JSONObject> { response ->
            // Display the first 500 characters of the response string.
            Log.d("Debug","Response is: ${response.toString()} ")

        }

有人愿意解释这一点或指向与此语法相关的一些参考资料吗?

标签: kotlinandroid-volley

解决方案


这是一个SAM 转换。因为Response.Listener<JSONObject>是一个 SAM 接口(有一个没有实现的单一方法default)并且是用 Java 定义的,所以你可以编写

Response.Listener<JSONObject> /* lambda */

并且 lambda 用作该方法的实现。即它相当于

object : Response.Listener<JSONObject> {
    override fun onResponse(response: JSONObject) {
        Log.d("Debug","Response is: ${response.toString()} ")
    }
}

推荐阅读