我在Kotlin工作,使用包含方法的Kotlin本地库对象.nameIsMuchTooLongAndIsStillNotClear.以类似的方式typealias,我想为方法创建一个别名,所以我可以将它称为某种东西.shortAndClear.稍微复杂一点,这些函数有几个参数,其中许多都有默认值,我不想在包装器中预处理.经过进一步的研究,它似乎仍然是一种扩展功能.
要使用示例函数,很容易测试,让我们说我要为创建别名类型的扩展String.startsWith被称为String.beg.我可以很容易地得到以下解决方案:
inline fun String.beg(prefix: CharSequence, ignoreCase: Boolean = false) = startsWith(prefix, ignoreCase) // works ok
Run Code Online (Sandbox Code Playgroud)
但是,这似乎要求我列出所有参数及其默认值,并为每次重载执行此操作.(真正的方法签名相当长,有更多的默认值.)本着"不要重复自己"的精神,有没有办法可以使用函数引用,String::startsWith这样我就不必枚举所有参数?我尝试了几种形式,但它们都不起作用:
// none of these work:
fun String.beg = String::startsWith
fun String.beg = this::startsWith
val String.beg: (CharSequence, Boolean) -> Boolean = String::startsWith
Run Code Online (Sandbox Code Playgroud) 我在部分函数应用程序的语法方面遇到问题。以下代码工作正常,并输出:two-three-four
import kotlin.coroutines.experimental.*
inline fun <T> Iterable<T>.forEachFrom(beg:Int, act:(T)->Unit) {
var i=0; if (beg>=0) for (e in this) if (i++ >= beg) act(e)
} // sample function I am testing; please don't change this!
fun main(a:Array<String>) {
val l = listOf("zero", "one", "two", "three", "four")
fun test() = buildSequence { l.forEachFrom(2) { yield(it) } }.joinToString("-")
println(test())
}
Run Code Online (Sandbox Code Playgroud)
我想封装我的test(),所以它被称为:
test(l.forEachFrom(2)) 但是,我似乎无法正确获取类型/语法。
我将如何重写test()函数定义以使其成为可能?
我有几个我无法控制的类,在这些类上我已经在几个常见的“属性”上创建了几个同名的扩展方法。名称相同的扩展函数始终返回相同的值类型,尽管针对每种类型的接收器以不同的方式计算。下面是一个基于仅一个属性的内置类型的简化示例:
// **DOES NOT COMPILE**
// three sample classes I don't control extended for .len
inline val String.len get() = length
inline val <T> List<T>.len get() = size
inline val <T> Sequence<T>.len get() = count()
// another class which needs to act on things with .len
class Calc<T>(val obj:T) { // HERE IS THE PROBLEM...
val dbl get() = obj?.len * 2 // dummy property that doubles len
// ... and other methods that use .len and …Run Code Online (Sandbox Code Playgroud) 是否可以接收具有保证返回类型R但参数数量可变的函数类型作为内联 lambda 参数?为简单起见,请考虑以下事项:
inline fun <R> Boolean?.tfn(tru:()->R, fls:()->R, nul:()->R) =
if (this == null) nul() else if (this) tru() else fls()
Run Code Online (Sandbox Code Playgroud)
假设我还有其他内联函数,它们也采用可能为or或类型的lambda 参数,我希望将其参数传递给该函数。它们都将提供 an但必须调用它们才能获取,而不知道该函数中参数的数量/类型/值。有没有办法将上面的函数一般修改为:(A)->R(A,B)->R(A,B,C)->RRR
R捕获返回其输入的任何 lambda 参数的一般情况我正在 Kotlin 中实现 vars,它可以接收来自某些用户的越界输入。我希望能够调用可选(只从这些非信任用户输入)进行验证的构造函数可以返回空值,然后使用Elvis操作符无效输入的情况下指定默认值,如: var myFoo = Foo.fromInt(i) ?: 1。我目前正在使用伴随对象方法来验证输入:
open class Foo(val x:Int) { // relies on valid x in 1..3
companion object {
fun fromInt(x: Int): Foo? = if (x in 1..3) Foo(x) else null
}
}
class Bar(x:Int) : Foo(x)
fun main(args:Array<String>) {
println(Foo.fromInt(2)) // Foo(2)
println(Foo.fromInt(20)) // null
// println(Bar.fromInt(2))
// would like Bar(2) but as expected, companion isn't inherited
}
Run Code Online (Sandbox Code Playgroud)
当我子类化时Foo,我知道我必须重新创建伴随对象。我试过从抽象类继承同伴;然而,调用Foo(x)仍然指向Foo而不是Bar,除非我fromInt在每个子类的同伴中覆盖。是否有更好或更符合 Kotlin 习惯的方法来处理这种可以返回null …
我经常在Kotlin内联函数中遇到错误,这些函数中必须标记lambda参数noinline。其他时候,lambda参数似乎可以正常工作。我已经阅读了Kotlin的内联函数文档,似乎这是解释该规则的有效段落:
不可嵌入的lambda只能在内联函数内部调用或作为不可嵌入的参数传递,但没有内联的lambda可以以我们喜欢的任何方式进行操作:存储在字段中,周围传递等。
我在解压缩这些概念时遇到了麻烦。具体来说,我不确定我是否完全理解使用内联lambda 不能做的事情(包括“等”中的所有内容),换句话说,那些会使其不符合内联条件的事情。 是否有很好的参考或更多解释/使用示例,这些示例使Kotlin lambda参数无法内联?
要么我的语法错误,要么你不能使用withto 应用于enum常量。IntelliJ 说这是因为RegexOption没有伴生对象,而RegexOption needs to be initialized here. 我不认为你可以实例化一个枚举。
// this works:
val RX_OPTIONS = mapOf(
'c' to RegexOption.COMMENTS,
'd' to RegexOption.DOT_MATCHES_ALL,
'e' to RegexOption.CANON_EQ,
'i' to RegexOption.IGNORE_CASE,
'l' to RegexOption.LITERAL,
'm' to RegexOption.MULTILINE,
'u' to RegexOption.UNIX_LINES
)
// this doesn't work:
val RX_OPTIONS2 = with(RegexOption) { mapOf(
'c' to COMMENTS,
'd' to DOT_MATCHES_ALL,
'e' to CANON_EQ,
'i' to IGNORE_CASE,
'l' to LITERAL,
'm' to MULTILINE,
'u' to UNIX_LINES
) }
Run Code Online (Sandbox Code Playgroud)
为什么第二个例子不起作用?如果它们不在伴生对象中,则它们似乎不会在实例中。有没有 …
kotlin ×7
lambda ×3
generics ×2
inline ×2
builder ×1
constructor ×1
enums ×1
polymorphism ×1
validation ×1