我正在尝试编写一个实质上是一些其他功能(例如某些日志记录功能)的包装方法的函数。
我尝试了inline
,generic
,reified
等的几种组合,但是似乎没有任何效果。
我的功能如下:
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
之类的方法来采取这种方法,但我无法弄清楚。
我想做的是可能的吗?如果没有,那附近有什么东西吗?
答案 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)
因为您要覆盖它并无论如何在那里实现其常规功能。