You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin类型不匹配错误:期望返回Unit却返回String的解决求助

解决Kotlin中OkHttp请求返回String的类型不匹配问题

问题原因

你当前用的是OkHttp的异步请求(enqueue方法),它不会阻塞当前线程,而是在请求完成后通过Callback接口的回调方法返回结果。你的getRequest函数没声明返回类型,默认返回Unit,但你在onResponse里的return result只是回调方法的返回,无法作为外层getRequest函数的返回值,因此出现Type mismatch错误。

下面是几种可行的解决方案:


方案1:改用同步请求(execute)

直接用execute发起同步请求,这种方式会阻塞当前线程,绝对不能在Android主线程或UI线程调用,否则会导致ANR。

private val client = OkHttpClient()

// 声明返回类型为String?,处理可能的异常
fun getRequest(id: String): String? {
    val url = "http://localhost:8000/api/v1/discord?discordid=$id"
    val request = Request.Builder()
        .url(url)
        .header("User-Agent", "OkHttp Bot")
        .build()

    return try {
        client.newCall(request).execute().use { response ->
            if (!response.isSuccessful) throw IOException("Unexpected code $response")
            response.body?.string()
        }
    } catch (e: IOException) {
        println("Error: ${e.message}")
        null
    }
}

如果是Android环境,需要把这个方法放到子线程中执行,比如用Thread或Coroutine包裹。


方案2:使用自定义回调作为参数

既然异步请求本身靠回调返回结果,可以给getRequest加一个回调参数,请求完成后调用回调传递结果。

private val client = OkHttpClient()

// 定义回调接口
interface RequestCallback {
    fun onSuccess(result: String)
    fun onFailure(error: String)
}

fun getRequest(id: String, callback: RequestCallback) {
    val url = "http://localhost:8000/api/v1/discord?discordid=$id"
    val request = Request.Builder()
        .url(url)
        .header("User-Agent", "OkHttp Bot")
        .build()

    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            callback.onFailure("Error: ${e.message}")
        }

        override fun onResponse(call: Call, response: Response) {
            response.use {
                try {
                    if (!response.isSuccessful) throw IOException("Unexpected code $response")
                    val result = response.body!!.string()
                    callback.onSuccess(result)
                } catch (e: IOException) {
                    callback.onFailure("Error: ${e.message}")
                }
            }
        }
    })
}

// 调用方式
getRequest("123456", object : RequestCallback {
    override fun onSuccess(result: String) {
        // 处理成功返回的字符串
        println(result)
    }

    override fun onFailure(error: String) {
        // 处理错误
        println(error)
    }
})

方案3:使用Kotlin协程(推荐)

协程是Kotlin处理异步操作的最优方式,既能避免回调地狱,又能写出类似同步代码的异步逻辑。需要先添加协程依赖,再将OkHttp请求包装成挂起函数。

步骤1:添加Gradle依赖

// 协程核心依赖
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
// Android环境额外添加
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
// OkHttp协程适配器(简化代码)
implementation "com.squareup.okhttp3:okhttp-coroutines:4.11.0"

步骤2:实现挂起函数

private val client = OkHttpClient()

// 用suspend声明挂起函数,返回String?
suspend fun getRequest(id: String): String? {
    val url = "http://localhost:8000/api/v1/discord?discordid=$id"
    val request = Request.Builder()
        .url(url)
        .header("User-Agent", "OkHttp Bot")
        .build()

    return try {
        // 用await()将异步请求转为挂起函数
        client.newCall(request).await().use { response ->
            if (!response.isSuccessful) throw IOException("Unexpected code $response")
            response.body?.string()
        }
    } catch (e: IOException) {
        println("Error: ${e.message}")
        null
    }
}

// 调用方式(必须在协程作用域内)
runBlocking {
    val result = getRequest("123456")
    result?.let { println(it) }
}

如果不想用OkHttp协程适配器,也可以手动用withContext(Dispatchers.IO)包裹同步请求:

suspend fun getRequest(id: String): String? = withContext(Dispatchers.IO) {
    val url = "http://localhost:8000/api/v1/discord?discordid=$id"
    val request = Request.Builder()
        .url(url)
        .header("User-Agent", "OkHttp Bot")
        .build()

    try {
        client.newCall(request).execute().use { response ->
            if (!response.isSuccessful) throw IOException("Unexpected code $response")
            response.body?.string()
        }
    } catch (e: IOException) {
        println("Error: ${e.message}")
        null
    }
}

内容的提问来源于stack exchange,提问作者Dollan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:40:54