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

时间:2019-05-27 10:50:14

标签: kotlin lambda parameter-passing

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

val _uiState = MutableLiveData<S>() 
var state: S
fun emit(reduction: S.() -> S) {
        state = reduction.invoke(state)
        if (_uiState.value != state) {
            _uiState.postValue(state)
        }
    }

1 个答案:

答案 0 :(得分:2)

为此,函数根本不是适当的类型。我会声明一个类型,其值对应于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)
    }
}

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