Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin Lambda作为函数参数->;仅接受来自特定类的方法_Kotlin_Lambda_Parameter Passing - Fatal编程技术网

Kotlin Lambda作为函数参数->;仅接受来自特定类的方法

Kotlin Lambda作为函数参数->;仅接受来自特定类的方法,kotlin,lambda,parameter-passing,Kotlin,Lambda,Parameter Passing,我希望找到一个解决方案,强制emit(S.()->S)函数接受泛型S类中的方法作为参数。当前解决方案接受返回S的所有lambda方法。 S是一个泛型类,它具有减少/修改自身参数的方法。我只希望在emit中调用这些方法。它保证传递给emit的每个方法都是“纯函数”(S中的所有方法都是纯函数) val\u uiState=MutableLiveData() 变量状态:S 乐趣排放(减少量:S.()->S){ state=reduce.invoke(状态) 如果(_uiState.value!=状态)

我希望找到一个解决方案,强制
emit(S.()->S)
函数接受泛型
S
类中的方法作为参数。当前解决方案接受返回S的所有lambda方法。 S是一个泛型类,它具有减少/修改自身参数的方法。我只希望在
emit
中调用这些方法。它保证传递给emit的每个方法都是“纯函数”(S中的所有方法都是纯函数)

val\u uiState=MutableLiveData()
变量状态:S
乐趣排放(减少量:S.()->S){
state=reduce.invoke(状态)
如果(_uiState.value!=状态){
_uiState.postValue(状态)
}
}

对于这一点,函数根本不是合适的类型。我要声明一个类型,其值对应于
S
的方法,所以

class S { 
    fun method1(x: String): S = ...
    fun method2(): S = ...
    ...

    sealed class Transform {
        operator fun invoke(s: S): S = when(this) {
            is Method1 -> s.method1(x)
            is Method2 -> s.method2()
            ...
        }

        class Method1(val x: String) : Transform
        object Method2 : Transform
    }
}

fun emit(reduction: S.Transform) {
    state = reduction.invoke(state)
    if (_uiState.value != state) {
        _uiState.postValue(state)
    }
}

通过一些努力,
转换
可以自动生成(例如,使用注释处理器,如您在注释中所述),但这可能不值得,这取决于您需要处理多少类和方法以及它们的更改频率。

您能解释一下为什么需要这样做吗?您的意思是允许调用
emit
的唯一合适的对象类型是
S
?您真的需要在这里重置
状态吗?仅仅使用一个消费者不是也有效吗?e、 g.:
fun emit(reduction:S.()->Unit){reduction(state)}
。。。你不能真的禁止使用其他函数。。。或者反过来说:您不需要使用给定的lambda参数。。。您也可以完全忽略它…我编辑了这个问题,以提供更多的上下文(我尝试做的事情并不明显),如果没有某种沙箱,这将是不可能的,这将导致太多的开销,除非您的lamda可能来自不受信任的源。关于限制客户端代码可以做什么的普遍共识是预先警告他们,并尽最大努力检测/防止不良行为。谢谢,这将解决我的问题。(记录调用的函数也会更容易)
class S { 
    fun method1(x: String): S = ...
    fun method2(): S = ...
    ...

    sealed class Transform {
        operator fun invoke(s: S): S = when(this) {
            is Method1 -> s.method1(x)
            is Method2 -> s.method2()
            ...
        }

        class Method1(val x: String) : Transform
        object Method2 : Transform
    }
}

fun emit(reduction: S.Transform) {
    state = reduction.invoke(state)
    if (_uiState.value != state) {
        _uiState.postValue(state)
    }
}