继承Kotlin中的函数类型

继承Kotlin中的函数类型,kotlin,inheritance,kotlin-function-type,Kotlin,Inheritance,Kotlin Function Type,Kotlin中有没有继承函数类型的方法? 我想要的是有这样一个成员:private lateinit var onPickedFunc:(Any)->Task?这样我就可以动态存储用户选择后需要运行的函数。例如: private fun showImagePicker(func: (Uri) -> Task<Void>?) { onPickedFunc = func val intent = Intent(

Kotlin中有没有继承函数类型的方法? 我想要的是有这样一个成员:
private lateinit var onPickedFunc:(Any)->Task?
这样我就可以动态存储用户选择后需要运行的函数。例如:

private fun showImagePicker(func: (Uri) -> Task<Void>?) {
        onPickedFunc = func
        val intent =
            Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI
            )
        startActivityForResult(intent, RC_PICK_IMAGE)
    }

private fun showMenu(func: (Context) -> Task<Void>?, v: View) {
        onPickedFunc = func
        PopupMenu(context, v).apply {
            // ProfileFragment implements OnMenuItemClickListener
            setOnMenuItemClickListener(this@ProfileFragment)
            inflate(R.menu.profile_settings_menu)
            show()
        }
    }
private-fun-showImagePicker(func:(Uri)->任务?){
onPickedFunc=func
瓦尔意图=
意图(
意向、行动、选择,
android.provider.MediaStore.Images.Media.INTERNAL\u CONTENT\u URI
)
startActivityForResult(意图,RC_拾取_图像)
}
私人娱乐展示菜单(func:(上下文)->任务?,v:视图){
onPickedFunc=func
弹出菜单(上下文,v)。应用{
//ProfileFragment实现OnMenuItemClickListener
setOnMenuItemClickListener(this@ProfileFragment)
充气(右菜单、外形设置菜单)
show()
}
}
我确实找到了一组名为
Function
的类,但它们都不允许在输入参数中继承(其中一个允许在输出参数中继承:
Function
)。 有没有办法做到这一点?
谢谢

我认为这里的问题是差异

func
是一个函数,其参数声明为
Uri

但是您的
onPickedFunc
属性将是一个参数可以是任何值的函数。您应该能够使用
Int
、或
Uri
、或
字符串或任何其他非空值来调用它

因此,您不能将
func
赋值给它,因为它(可能)无法处理
Int
字符串或任何东西

在技术术语中,类型不兼容。功能参数在
方差(逆变)中有
;要成为子类型,它必须接受每个参数的超类型。(这与函数的返回类型相反,它具有
out
variance AKA convariance。)因此编译器将标记类型不匹配

如果要在属性中存储
(Uri)->Task
函数,它必须是
(Uri)->Task
类型或某种超类型,这意味着函数必须接受
Uri
或某种子类型

(我不知道你的
Uri
是什么类型,但是如果它是
final
,比如
java.net.Uri
,那么唯一的子类型就是
Uri
本身。)



顺便说一下,
kotlin.jvm.functions.Function…
接口是一个实现细节;编译器使用它们在JVM上实现函数类型,但它们不是您应该在代码中引用的东西(我认为在反射等特殊情况下除外)。

感谢您的快速响应和解释!我现在明白了为什么将
Any
作为参数类型存在问题。我仍然希望避免每个可能的后续活动都有一名成员。是否有一种合乎逻辑的方式将属性定义为“获取任何类型的一个参数的函数”?因此,在我的
onActivityResult
中调用它之前,我将能够将它转换为它的子类型“function get one
Uri
param”,并在我的
onMenuItemClick
中转换为它的子类型“function get one
Context
param”,依此类推。。。或者你有没有其他的建议来巧妙地解决这个问题?谢谢:)如果您有其他方法知道它将接受什么参数类型,您可以将其存储为
(Nothing)->Task
,因为它是每种类型的子类型。 您不能直接调用它,因为它没有实例,但是您可以在调用它之前将它向上转换为特定类型。 (在其他情况下,您可以使用
*
来表示“我们不知道这里的某些特定类型”,但这在这里不起作用。)我在阅读您的答案时尝试了第一件事,但当我尝试转换它时:
(onPickedFunc as((Uri)->任务?)
我收到“未选中的转换:(无)->任务?到(Uri)->任务?”警告,当我尝试检查它时:
(onPickedFunc是((Uri)->任务?)
我得到“无法检查擦除类型的实例:(Uri)->任务?”错误。是的,您将得到“Unchecked cast”,但这只是一个警告:它告诉您编译器无法确保它的安全,因此由您来确定。您将无法检查
Void
部分-正如另一条警告所说,这是一个在运行时被擦除的泛型类型。不过,您可以检查其余部分,如果您可以从代码的其余部分看出参数总是
Void
,那么您可以忽略警告。这应该如何在界面中实现?用户正在键入kotlin lambda自己的代码?或者用户正在选择一个可能的预定义选项?