如何使用 kotlin 函数式编程访问 属性

How to use kotlin functional programming to access a property

我目前有以下功能:

fun createMask(mask : String){
    val ssnField : mywidgets.SSNField = findViewById (R.id.editTextText)
    ssnField.hint = mask
}

为了对此进行单元测试,我想将 createMask 中不可测试的代码包装到一个闭包中。 (不可测试的代码是很难在单元测试中实例化和执行的视图层逻辑。)下面是我想在伪代码中做的事情:

createMask(closure, mask : String){
    closure = mask  // closure function returns pointer to property (depending on closure return type, might need to use setter: closure.set(mask))
}

有了上面的内容,调用者会做:

fun caller(){
    createMask((){
        val ssnField : mywidgets.SSNField = findViewById (R.id.editTextText)
        return ssnField.hint
    }, "xxx-xx-xxx")
}

伪代码中表达的内容如何在 kotlin 中工作?

如果让 createMask 接受 () -> KMutableProperty0<String> 类型的参数,则可以 return 引用 属性。然后就可以调用set方法:

fun createMask(mask : String, block: () -> KMutableProperty0<String>) {
    block().set(mask)
}

// caller

createMask("xxx-xx-xxx") {
    val ssnField = ...
    ssnField::hint
}

或者,使用 (String) -> Unit 表示“任何接受字符串的函数”,如果您希望允许调用者传递具有 setter 的“形式”的任何函数。

fun createMask(mask : String, block: () -> (String) -> Unit) {
    block()(mask)
}

// caller

createMask("xxx-xx-xxx") {
    val ssnField = ...
    ssnField::hint.setter
}

请注意,此方法涉及反射,这可能是不可取的。或者,您可以接受一个接受要设置的字符串的闭包,并让调用者在闭包中设置它:

fun createMask(mask: String, block: (String) -> Unit) {
    block(mask)
}

// caller

createMask("xxx-xx-xxx") {
    val ssnField = ...
    // note that rather than responsible for returning a property, the caller 
    // is responsible for setting "it" to the property
    ssnField.hint = it
}

(我假设 createMask 不仅仅是设置一个 属性。否则它毫无意义...)