【问题标题】:Inline alias for Kotlin function that includes generics?包含泛型的 Kotlin 函数的内联别名?
【发布时间】:2017-12-06 23:03:50
【问题描述】:

根据我在an earlier question 中收到的建议,我用“别名”缩短了一些常用的外来函数(我无法控制)的名称。这对于扩展功能很有效;但是,我还有一些我想别名的顶级函数。对于一个简化的示例,请考虑 generateSequence 函数。我希望能够做到这一点:

// DOES NOT COMPILE
inline val <T:Any> seq:(()->T?)->Sequence<T> get() = ::generateSequence

...但我不能,因为必须在接收器类型中使用泛型,正如in this answer 所解释的那样。是否有任何其他方法可以为保留内联的顶级函数(需要泛型)创建 别名?

编辑:我在发布问题后立即尝试使用Any? 和星形投影,但我仍然认为这不是一个好的答案:

inline val seq:(()->Any?)->Sequence<*> get() = ::generateSequence

这似乎是最理想的,因为它损害了对序列元素类型的类型检查,对吗?关于什么可行的其他答案/想法?

【问题讨论】:

    标签: generics properties kotlin inline


    【解决方案1】:

    您可以使用的一个选项是重命名导入,但它仅限于单个源文件:

    import kotlin.sequences.generateSequence as seq
    
    fun main(args: Array<String>) {
        seq(1) { it + 1 }.take(10).forEach(::println)
    }
    

    除此之外,我认为你能做的最好的事情就是退回到声明另一个内联函数:

    inline fun <T> seq(nextFunction: () -> T?) = 
        generateSequence(nextFunction)
    

    事实上,我希望此选项的性能比具有函数引用的选项更好,因为当您调用该引用时,使用返回函数引用的内联属性仍然有一些开销,而此调用是内联调用,因此不会为另一个嵌套调用引入开销。

    【讨论】:

    • 我喜欢你的内联函数方法,但我认为这会返回一个illegal use of inline-parameter 错误。我使用了 inline 属性,因为即使在询问 this question earlier 之后,我也找不到另一种内联方式。你认为内联属性(函数引用)会比带有noinline lambda 参数的函数执行得更差(假设我正在谈论一个我可以做到的函数——即不需要泛型)?
    猜你喜欢
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多