Kotlin-有没有一种方法可以定义一个函数的显式作用域,并在伴随对象中定义接收方?

Kotlin-有没有一种方法可以定义一个函数的显式作用域,并在伴随对象中定义接收方?,kotlin,kotlin-extension,Kotlin,Kotlin Extension,假设您有以下代码: interface SomeClient { fun isValid(value: String): Boolean } class SomeData private constructor( val value: String ) { companion object { fun SomeClient.create(value: String): SomeData? = if (isValid(valu

假设您有以下代码:

interface SomeClient {

    fun isValid(value: String): Boolean
}

class SomeData private constructor(
    val value: String
) {

    companion object {

        fun SomeClient.create(value: String): SomeData? =
            if (isValid(value)) {
                SomeData(value)
            } else {
                null
            }
    }
}

class SomeOtherData private constructor(
    val otherValue: String
) {

    companion object {

        fun SomeClient.create(value: String): SomeOtherData? =
            if (isValid(value)) {
                SomeOtherData(value)
            } else {
                null
            }
    }
}

class SomeUseCase(
    someClient: SomeClient
) : SomeClient by someClient {

    fun run() {
        val someData = SomeData.create("hello")
        val someOtherData = SomeOtherData.create("wassup")
    }
}
整个目的是提供一个静态工厂方法来创建有效的值对象(
SomeData
SomeOtherData
),但验证逻辑包括一些IO操作。因此,我想将create方法的调用范围限制为实现
SomeClient
的类

这里的问题是编译器无法解析
SomeUseCase#run
中的伴生对象方法(
SomeData#create
SomeOtherData#create
),它会抱怨接收器不正确

我当然可以这样做

class SomeUseCase {
    fun run() {
        val someData = this.createSomeData(...)
        val someOtherData = this.createSomeOtherData(...)
    }
}
并相应地重命名创建方法,但我希望保留名称,使其成为
SomeData.create
,而不是
SomeData.createSomeData


有没有办法做到这一点?这有意义吗?

当您编写
有趣的SomeClient.create(value:String)
SomeData
伴生对象中,您不是在为伴生对象定义
create
方法,而是在伴生对象范围内为
SomeClient
定义方法

如果重写它,使其成为伴生对象的方法,您将看到,
isValid
()调用没有接收器,因此需要将其作为参数传递到那里:

class SomeData私有构造函数(val值:字符串){
伴星{
有趣的创建(值:字符串,验证器:SomeClient):SomeData=
if(validator.isValid(value))SomeData(value)else null
}
}
之后,可以在
SomeClient
的范围内调用它,如下所示:

val someData=someData.create(“hello”,this)
对每个创建调用重复
这个
有点麻烦,因此您可以在
SomeClient
接口的范围内为
SomeData
伴随对象定义一个扩展函数:

interface SomeClient{
fun是有效的(值:字符串):布尔值
fun SomeData.Companion.create(value:String)=create(value,this@SomeClient)
}
之后,可以在
SomeClient
的范围内以所需的方式调用它:

val someData=someData.create(“你好”)