Kotlin:排序 |交换操作的位置
Kotlin: Sorting | Location of swap operation
我正在 Kotlin 中实现快速排序算法。为此,我创建了一个接口 ISort,带有一个类型参数和一个函数 sort。为了排序,我需要交换操作。我想知道这个交换功能的最佳位置是什么。我的想法:
1) 不幸的是,在 Kotlin 中不能使接口函数受到保护。因此,每个 class 都可以在其实现中看到交换,这不是太好(虽然也不是太糟糕,我同意)。
2) 将它放在 QuickSort 实现中更糟糕,因为可能有多个 ISort 接口的实现需要交换函数。
3) 我的下一个想法是创建一个单例对象,但 Kotlin 允许带有类型参数的对象。
接口定义如下:
interface ISort<T> {
fun sort(toSort: MutableList<T>): MutableList<T>
// 1) Putting swap here has a too high visibility
}
这是快速排序的框架class:
class QuickSort<T> : ISort<T> {
override fun sort(toSort: MutableList<T>): MutableList<T> {
doQuickSort(toSort) // Internally uses swap
return toSort
}
// 2) Putting swap here might lead to code duplication of swap
}
因此,从软件工程的角度来看,交换操作的最佳地点/位置是什么。
顶级函数
在文件 sort.kt
左右,
package abc.def.sort
fun <T> quicksort(list: MutableList<T>): MutableList<T> {
...
}
// invisible in other files, but visibie in "sort.kt"
private fun <T> swap(...) {
...
}
要在其他排序中使用 swap
函数,您需要在同一文件中定义其他排序函数。 (或者多次复制swap
函数。)
推荐用于非常简单的函数。
作为命名空间的对象
这与上面的方法类似,但比上一个更符合 OOP。
object QuickSort {
fun <T> sort(list: MutableList<T>): MutableList<T> {
...
}
private fun <T> swap(...) {
...
}
}
或
object Sorts {
fun <T> quicksort(list: MutableList<T>): MutableList<T> {
...
}
// add other sort methods...
private fun <T> swap(...) {
...
}
}
但是,在 Kotlin (Best practices for top-level declarations) 中不推荐这样做。
抽象class和对象
的组合
swap
函数可以通过这种方式重复用于其他排序。
abstract class Sort {
abstract fun <T> sort(list: MutableList<T>): MutableList<T>
protected fun <T> swap(...) {
...
}
}
object QuickSort : Sort() {
override fun <T> sort(list: MutableList<T>): MutableList<T> {
...
}
}
我认为[使类型参数 T
成为 class 类型参数,而不是函数类型参数] 会使问题不必要地变得更加复杂,因为您将不得不创建一个 class 每次使用不同类型的实例 T
.
我正在 Kotlin 中实现快速排序算法。为此,我创建了一个接口 ISort,带有一个类型参数和一个函数 sort。为了排序,我需要交换操作。我想知道这个交换功能的最佳位置是什么。我的想法:
1) 不幸的是,在 Kotlin 中不能使接口函数受到保护。因此,每个 class 都可以在其实现中看到交换,这不是太好(虽然也不是太糟糕,我同意)。
2) 将它放在 QuickSort 实现中更糟糕,因为可能有多个 ISort 接口的实现需要交换函数。
3) 我的下一个想法是创建一个单例对象,但 Kotlin 允许带有类型参数的对象。
接口定义如下:
interface ISort<T> {
fun sort(toSort: MutableList<T>): MutableList<T>
// 1) Putting swap here has a too high visibility
}
这是快速排序的框架class:
class QuickSort<T> : ISort<T> {
override fun sort(toSort: MutableList<T>): MutableList<T> {
doQuickSort(toSort) // Internally uses swap
return toSort
}
// 2) Putting swap here might lead to code duplication of swap
}
因此,从软件工程的角度来看,交换操作的最佳地点/位置是什么。
顶级函数
在文件 sort.kt
左右,
package abc.def.sort
fun <T> quicksort(list: MutableList<T>): MutableList<T> {
...
}
// invisible in other files, but visibie in "sort.kt"
private fun <T> swap(...) {
...
}
要在其他排序中使用 swap
函数,您需要在同一文件中定义其他排序函数。 (或者多次复制swap
函数。)
推荐用于非常简单的函数。
作为命名空间的对象
这与上面的方法类似,但比上一个更符合 OOP。
object QuickSort {
fun <T> sort(list: MutableList<T>): MutableList<T> {
...
}
private fun <T> swap(...) {
...
}
}
或
object Sorts {
fun <T> quicksort(list: MutableList<T>): MutableList<T> {
...
}
// add other sort methods...
private fun <T> swap(...) {
...
}
}
但是,在 Kotlin (Best practices for top-level declarations) 中不推荐这样做。
抽象class和对象
的组合swap
函数可以通过这种方式重复用于其他排序。
abstract class Sort {
abstract fun <T> sort(list: MutableList<T>): MutableList<T>
protected fun <T> swap(...) {
...
}
}
object QuickSort : Sort() {
override fun <T> sort(list: MutableList<T>): MutableList<T> {
...
}
}
我认为[使类型参数 T
成为 class 类型参数,而不是函数类型参数] 会使问题不必要地变得更加复杂,因为您将不得不创建一个 class 每次使用不同类型的实例 T
.