我是一个长期的Java程序员,但最近我决定给Kotlin一次尝试。到目前为止,我喜欢语言的特点,感觉比我习惯的更有表现力。作为实践,我编写了这个函数,它生成一个可重复的素数序列(即,该序列可以被多次迭代,并将利用过去迭代的结果来加快未来的迭代)。对我来说,这感觉很稳固,但是我想知道在科特林的老将那里会是什么样子--我有没有充分利用语言的特点,或者我应该遵循的惯例?
我有一个特别的问题是关于顶级函数与子类的问题;这里我选择实现一个返回一个primeSequence(): Sequence<Long>的顶级函数object,但是我可以很容易地实现一个类PrimeSequence : Sequence<Long>。在什么时候使用其中一种或另一种是否有很好的经验法则?
fun primeSequence(): Sequence<Long> = object: Sequence<Long> {
private val knownPrimes: MutableList<Long> = arrayListOf(2L, 3L)
private fun Long.isMultipleOf(n: Long) = (this%n == 0L)
private fun Long.isPrime() = knownPrimes
.takeWhile { it*it <= this }
.none { this.isMultipleOf(it) }
override fun iterator(): Iterator<Long> = object: Iterator<Long> {
private var lastPrime: Long? = null
override fun hasNext() = true
override fun next(): Long {
val nextPrime = when(val lastPrime = this.lastPrime) {
null -> 2L
2L -> 3L
else -> {
if (knownPrimes.last() > lastPrime ) {
knownPrimes[knownPrimes.binarySearch(lastPrime) + 1]
} else {
val np = generateSequence(lastPrime+2) { it+2 }
.first { it.isPrime() }
knownPrimes.add(np)
np
}
}
}
this.lastPrime = nextPrime
return nextPrime
}
}
}发布于 2020-12-20 20:09:34
我不喜欢这样返回继承Sequence<Long>的内联对象的想法。Kotlin有几个特性可以帮助您构建东西,包括一个用于序列的特性。
使用Kotlin中的sequence构建器的强大功能(在表面下面是内部使用可悬浮函数 ),我们可以逐个实现yield,而不是实现Iterator。
我们可以重写代码以使用外部object来保持全局状态,然后使用函数生成序列。
object Primes {
private val knownPrimes: MutableList<Long> = mutableListOf(2L, 3L)
private fun Long.isMultipleOf(n: Long) = (this % n == 0L)
private fun Long.isPrime() = knownPrimes
.takeWhile { it * it <= this }
.none { this.isMultipleOf(it) }
fun sequence(): Sequence<Long> {
var lastPrime: Long? = null
return sequence {
while (true) {
val nextPrime = when(val actualLastPrime = lastPrime) {
null -> 2L
2L -> 3L
else -> {
if (knownPrimes.last() > actualLastPrime) {
knownPrimes[knownPrimes.binarySearch(actualLastPrime) + 1]
} else {
val np = generateSequence(actualLastPrime + 2) { it+2 }
.first { it.isPrime() }
knownPrimes.add(np)
np
}
}
}
lastPrime = nextPrime
yield(nextPrime)
}
}
}
}https://codereview.stackexchange.com/questions/253690
复制相似问题