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
相关产品推荐
相关产品推荐

