gpt4 book ai didi

kotlin - 自定义 'typesafe' Int 类型

转载 作者:行者123 更新时间:2023-12-02 13:01:52 25 4
gpt4 key购买 nike

我想要的是两种不同的整数类型,它们在语义上是可区分的。

例如。在这段代码中,一个 'Meter' 类型和一个 'Pixel' int 类型

typealias Meter = Int
typealias Pixel = Int

fun Meter.toPixel() = this * 100
fun Pixel.toMeter() = this / 100

fun calcSquareMeters(width: Meter, height: Meter) = width * height
fun calcSquarePixels(width: Pixel, height: Pixel) = width * height

fun main(args: Array<String>) {
val pixelWidth: Pixel = 50
val pixelHeight: Pixel = 50

val meterWidth: Meter = 50
val meterHeight: Meter = 50

calcSquareMeters(pixelWidth, pixelHeight) // (a) this should not work

pixelWidth.toPixel() // (b) this should not work
}

这个解决方案的问题是

(a) 我可以用我不希望的“像素”类型调用 calcSquareMeters,并且

(b) 我可以调用 toPixel() 扩展函数,我只想在我的 'Pixel' 类型上使用我的 'Meter' 类型,而我不想这样做。

我想这是 typealias 的预期行为,所以我想为了实现我的目标,我必须使用不同于 typealias 的东西......

那么我该如何实现呢?

最佳答案

除了现有的answer :如果您在两种类型之间有很多共同的功能并且不想重复它,您可以使用接口(interface):

interface MetricType<T> {
val value: Int

fun new(value: Int): T
}

data class Meter(override val value: Int) : MetricType<Meter> {
override fun new(value: Int) = Meter(value)
}

data class Pixel(override val value: Int) : MetricType<Pixel> {
override fun new(value: Int) = Pixel(value)
}

像这样,您可以轻松地在基本接口(interface)上定义操作,例如加法、减法和缩放:
operator fun <T : MetricType<T>> T.plus(rhs: T) = new(this.value + rhs.value)
operator fun <T : MetricType<T>> T.minus(rhs: T) = new(this.value + rhs.value)
operator fun <T : MetricType<T>> T.times(rhs: Int) = new(this.value * rhs)

接口(interface)和泛型的结合确保了类型安全,因此您不会意外混合类型:
fun test() {
val m = Meter(3)
val p = Pixel(7)

val mm = m + m // OK
val pp = p + p // OK
val mp = m + p // does not compile
}

请记住,由于虚拟功能,此解决方案需要运行时成本(与分别为每种类型重写运算符相比)。除了对象创建的开销之外。

关于kotlin - 自定义 'typesafe' Int 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51057679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com