是否可以声明一个只返回的函数null
?不幸的是,你不能null
在返回类型部分写.返回值应该是null
而不是Unit,以便它可以与可空操作符一起使用.
我想在多个类中使用此函数:
fun <T> T?.ifNull(function: (T?, s:String) -> Unit) {
}
Run Code Online (Sandbox Code Playgroud)
我怎么能做到这一点?
这就是我想用它的方式:
class A{
fun <T> T?.ifNull(function: (T?, s:String) -> Unit) {
}
}
class B{
constructor(){
val a = A()
//I want to use the function here
}}
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个断言函数来检查给定的对象是否属于某个类型T
:
@UseExperimental(ExperimentalContracts::class)
inline fun <reified T> assertIsInstance(value: Any?) {
contract {
returns() implies (value is T)
}
Assertions.assertThat(value).isInstanceOf(T::class.java)
}
Run Code Online (Sandbox Code Playgroud)
该函数使用 AssertJ 来做具体的断言,但我愿意让编译器知道在它执行后,value
is 的类型T
是可以进行智能广播的。这似乎不起作用,因为:
Error in contract description: references to type parameters are forbidden in contracts
有没有另一种方法来实现这种行为?这里有什么问题?这最终会成为可能吗?
(使用 Kotlin v1.3)
generics kotlin assertj kotlin-reified-type-parameters kotlin-contracts
我Math
在Kotlin中添加了一个函数,但是我无法使用它,我之前使用它MutableList
并且它有效但我无法用Math
类来完成它.
fun Math.divideWithSubtract(num1: Int, num2: Int) =
Math.exp(Math.log(num1.toDouble())) - Math.exp(Math.log(num2.toDouble()))
Run Code Online (Sandbox Code Playgroud) 在Kotlin中,可以使用这样的反向标记命名方法:
fun `i am a test method`(){
Assert.assertEquals("x", "x")
}
Run Code Online (Sandbox Code Playgroud)
所述编译器生成用下划线代替坯件的方法,包括:"i_am_a_test_method",因为JVM不这似乎合理不允许用空白方法AFAIK.Junit和/或Gradle如何使用反向标记的名称报告这些测试?
我有一个Job
实例列表,我希望在发布后的某个时刻取消.这看起来如下:
val jobs = arrayListOf<Job>()
//launch and add jobs...
jobs.forEach { it.cancelAndJoin() } // cancels the jobs and waits for completion
Run Code Online (Sandbox Code Playgroud)
不幸的是,这里不可能使用方法参考.原因:cancelAndJoin
是一个suspend
函数,因为编译器抱怨:
jobs.forEach (Job::cancelAndJoin)
Run Code Online (Sandbox Code Playgroud)
"错误:(30,24)Kotlin:不支持[可暂停函数的可调用引用]"
为什么这不起作用?
我正在阅读Kotlin
参考文件,然后我看到了这一点.
类声明由类名,类头(指定其类型参数,主构造函数等)和类主体组成,由大括号括起.标题和正文都是可选的; 如果类没有主体,可以省略花括号.
class Empty
Run Code Online (Sandbox Code Playgroud)
现在我想知道没有标题和正文的这种类声明的用途是什么
我想为var
属性做一个懒惰的初始化.由于by lazy
仅限于val
属性我必须写这样的东西:
private var currentContextProvider: ContextProvider? = null
get() {
if (field == null) {
field = DefaultContextProvider()
}
return field
}
Run Code Online (Sandbox Code Playgroud)
现在我必须处理那些毫无意义的可控性通知:currentContextProvider?.getContext()
或者说currentContextProvider!!.getContext()
难道我做错了什么?
根据以下源代码,似乎常规lambda可以与扩展lambdas互换.
fun main(args: Array<String>) {
val numbers = listOf(1, 2, 3)
filter(numbers, predicate)
filter(numbers, otherPredicate)
println("PREDICATE: ${predicate} " +
"\nOTHERPREDICATE: ${otherPredicate} " +
"\nEQUALITY: ${predicate==otherPredicate}")
}
val predicate : Int.() -> Boolean = {this % 2 != 0}
val otherPredicate : (Int) -> Boolean = {it % 2 != 0}
fun filter(list: List<Int>, predicate:(Int) -> Boolean) {
for(number in list){
if(predicate(number)){
println(number)
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出(我关心),如下:
PREDICATE: kotlin.Int.() -> kotlin.Boolean
OTHERPREDICATE: (kotlin.Int) -> kotlin.Boolean
EQUALITY: false
Run Code Online (Sandbox Code Playgroud)
问题是为什么这些lambdas可以互换?不应该是不同的东西?编译器是否在做一些"聪明"的事情?
我试图在列表中找到符合条件(过滤)的前两个元素,为此我在kotlin中实现了以下代码:
val arr = 0 until 20
val res = arr.filter { i ->
println("Filter: $i")
i % 2 == 0
}.take(2)
Run Code Online (Sandbox Code Playgroud)
一切都很好,直到我意识到它过滤整个列表,无论是否找到了这两个元素.
使用Java 8 stream api,它按预期工作.
val res2 = arr.toList().stream()
.filter { i ->
println("Filter: $i")
i % 2 == 0
}.limit(2)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是如果只使用Kotlin功能就可以实现.
我知道我可以使用一个简单的for循环,但我想使用函数式编程方法.