Kotlin-自动匹配替代功能类型吗?

时间:2019-06-25 03:45:19

标签: kotlin

我正在尝试编写一个实质上是一些其他功能(例如某些日志记录功能)的包装方法的函数。

我尝试了inlinegenericreified等的几种组合,但是似乎没有任何效果。

我的功能如下:

fun log(note: String, block: () -> Unit): () -> Unit {
    print(note)
    return block
}

我在这里的想法是对传入的note执行一些简单的操作,然后仅返回该传入的函数即可使用。

但是,我想围绕这样的覆盖函数执行此操作:

override fun onClick(clicked: View) = log("Green Button") {
    // here the regular onClick functionality goes
}

在这里,我收到一个错误“ 返回类型为()->单位,它不是被覆盖的子类型”。这很有意义,因为功能签名不匹配。

但是,当我使用其他随机函数执行此操作时:

fun test() = log("foo") { ... }
fun otherTest(a: String, b: Int) = log("bar") { ... }

我没有错误,解释器对此似乎还不错。我也尝试使用GlobalScope.launch之类的方法来采取这种方法,但我无法弄清楚。

我想做的是可能的吗?如果没有,那附近有什么东西吗?

3 个答案:

答案 0 :(得分:0)

如果我的理解错误,请告诉我。这是我的方法

扩展功能:

fun View.onClickWithLog(str: String, l: () -> Unit) {
    setOnClickListener { Log.d("LogTag", str); run(l) }
}

用法(来自Activity):

btnTest.onClickWithLog("My Button String"){
            Log.d("Actions from Activity", "Content")
            finish()
        }

,输出为

 D/LogTag: My Button String
 D/Actions from Activity: Content

首先打印您的笔记,然后执行lambda表达式中的操作。

答案 1 :(得分:0)

我认为

inline fun log(note: String, block: () -> Unit): Unit {
    print(note)
    return block()
}

应该做你想要的。可以概括为

inline fun <T> log(note: String, block: () -> T): T {
    print(note)
    return block()
}
  

我没有错误,解释器对此似乎还不错。

那为什么令人惊讶?这些函数仅返回() -> Unit。如果您这样做,例如

fun test() = log("foo") { print("bar") }

然后调用test()不会打印bar;会打电话给test()()

答案 2 :(得分:0)

当您使用=运算符向fun分配内容时,右侧的表达式应该返回该fun的返回类型

原始fun onClick(clicked:View) : Unit的返回类型为Unit。当你写

override fun onClick(clicked:View) = ......是您致电onClick(v)时得到的,因此应该是Unit而不是View -> Unit(甚至不是{{ 1}},就像您的代码一样

举一个简单的例子。假设您有() -> Unit。当您编写fun sum(a:Int,b:Int) : Int时,override fun sum(a:Int,b:Int) = ...必须是...而不是Int,因为您希望在致电(Int,Int) -> Int时立即得到Int 。如果您以某种方式让

sum(a,b)

并想使用它,您可以编写

val someOtherWayToSum : (Int,Int) -> Int = {...}

就您而言,最好还是

override fun sum(a:Int,b:Int) = someOtherWayToSum(a,b)

因为您要覆盖它并无论如何在那里实现其常规功能。