kotlin - Kotlin 接口函数作为表达式主体
问题描述
当在 Kotlin 中编写一个函数时,它基本上是在一个Thread
创建内部完全实现的start()
,Android Studio 提供了“转换为表达式主体”的选项
选择这样做时,Kotlin将功能转换为表达式主体:
有没有办法要求这个接口(比如这个函数覆盖的那个)?
我希望接口始终要求validate
函数启动一个新的Thread
并且只有(!!)能够执行 that 里面的东西Thread
,而不是方法体本身,因为它只会用于寻址服务器。
abstract class
我知道我可以通过使用一个而不是这样的来强制这种行为interface
:
abstract class ServerValidator<T> {
fun validate(value: T?, function: ((ValidationResult) -> Unit)) = Thread {
doValidation(value, function)
}.start()
protected abstract fun doValidation(value: T?, function: ((ValidationResult) -> Unit))
}
这样一个继承类将能够覆盖该doValidation
函数,而另一个类只能调用validate
并因此总是使用一个新线程。
但是,我特别想知道是否可以用接口做这样的事情。
就像是:
interface ServerValidator<T> {
fun validate(value: T?, function: ((ValidationResult) -> Unit)) = Thread::start
}
// or
interface ServerValidator<T> {
fun validate(value: T?, function: ((ValidationResult) -> Unit)) : Thread::start
}
解决方案
表达式主体与函数签名无关。它纯粹是一种语法替代方案。在您的示例的两种情况下,该函数都返回Unit
,因为在表达式主体情况下,它返回的是Thread.start()
返回的内容,即Unit
.
我认为您实际上要问的是您是否不仅可以定义函数返回的内容,还可以定义它如何获得该结果的中间步骤,即强制它在后台线程上执行某些操作。答案是否定的。语言中没有任何东西可以定义这样的结构。
您已经描述了正确的方法,即采用函数参数,然后接收类可以自己在后台线程中调用它。
另一种方法可能是将函数定义为suspend
函数,这意味着它不应该在不使用适当的协程 Dispatcher 来执行阻塞代码的情况下执行阻塞代码。然后,如果实现接口函数的人未能使用后台调度程序,他们就违反了suspend
函数应该如何工作的约定。但是编译器仍然不会强迫他们正确地做到这一点。
推荐阅读
- vb.net - 重复检查
- google-sheets-api - 我无法激活 Google Sheets API
- scala - 如何为 Spark 强制使用 Scala 版本?
- .net-core - Application Insights:在 .net core 3.1 控制台应用程序中通过自定义 ITelemetryInitializer 添加云角色名称不会获取云角色名称
- javascript - 如何在 JavaScript 突围游戏中将球保持在墙边界内?
- angular - 如何使 owl-carousel-o 让每个图像在 angular8 中占据整个屏幕?
- ssl - 想知道如何在启用基本身份验证的情况下向 HTTPS 应用程序发出请求
- python - 使用 scikit-learn 的 SGDClassifier 实现 SVM:如何调整正则化参数?
- php - 重定向 https://
/store 到 https://store。 / - flutter - 如何从 Navigator 中的字符串创建类(页面)