我经常发现自己为number类型创建了很多重载,因为Kotlin不会对非文字进行隐式转换。这导致了大量重复的重载函数,这是大量的样板文件。
我这样做的痛苦的一个例子可以在这里看到:https://github.com/Jire/Arrowhead/blob/master/src/main/kotlin/org/jire/arrowhead/Source.kt
我理解隐式转换会导致错误的原因,但我认为在大多数情况下,特别是对于像Byte -> Int和Int -> Long这样不会丢失数据的“放大”转换,应该有更好的方法。
所以..。我的问题是,你是如何处理这个问题的?有没有什么创造性的方法来解决这个问题?
发布于 2016-07-24 15:23:28
回答您的问题:您可以在Number中使用泛型函数。然后,它将接受Number的任何子类型。然后,您可以将该值转换为任何其他数值类型:
fun boo(x: Number) {
    val y = x.toLong()
    println(y is Long)
} 这样做的唯一缺点是自动装箱,但这对您的情况应该无关紧要。
关于你发布的代码:我相信你有一些架构错误导致了这种情况。这里是你的API,没有太多的细节:
interface Source {
    fun read(address: Long, data: Pointer, bytesToRead: Int) 
    fun read(address: Int, data: Pointer, bytesToRead: Int) = read(address.toLong(), data, bytesToRead)
    fun read(address: Long, data: Memory, bytesToRead: Int = data.size().toInt()) = read(address, data as Pointer, bytesToRead)
    fun read(address: Int, data: Memory, bytesToRead: Int = data.size().toInt()) = read(address.toLong(), data, bytesToRead)
    fun read(address: Long, struct: Struct, bytesToRead: Int = struct.size()) = read(address, struct.pointer, bytesToRead)
    fun read(address: Int, struct: Struct, bytesToRead: Int = struct.size()) = read(address.toLong(), struct, bytesToRead)
    fun read(address: Long, bytesToRead: Int): Memory = TODO()
    fun read(address: Int, bytesToRead: Int) = read(address.toLong(), bytesToRead)
    fun byte(address: Long, offset: Long = 0) = read(address, 1).getByte(offset)
    fun byte(address: Int, offset: Long = 0) = byte(address.toLong(), offset)
    fun short(address: Long, offset: Long = 0) = read(address, 2).getShort(offset)
    fun short(address: Int, offset: Long = 0) = short(address.toLong(), offset)
    fun char(address: Long, offset: Long = 0) = read(address, 2).getChar(offset)
    fun char(address: Int, offset: Long = 0) = char(address.toLong(), offset)
    fun int(address: Long, offset: Long = 0) = read(address, 4).getInt(offset)
    fun int(address: Int, offset: Long = 0) = int(address.toLong(), offset)
    fun long(address: Long, offset: Long = 0) = read(address, 8).getLong(offset)
    fun long(address: Int, offset: Long = 0) = long(address.toLong(), offset)
    fun float(address: Long, offset: Long = 0) = read(address, 4).getFloat(offset)
    fun float(address: Int, offset: Long = 0) = float(address.toLong(), offset)
    fun double(address: Long, offset: Long = 0) = read(address, 8).getDouble(offset)
    fun double(address: Int, offset: Long = 0) = double(address.toLong(), offset)
    fun boolean(address: Long, offset: Long = 0) = byte(address, offset).unsign() > 0
    fun boolean(address: Int, offset: Long = 0) = boolean(address.toLong(), offset)
    fun write(address: Long, data: Pointer, bytesToWrite: Int)
    fun write(address: Int, data: Pointer, bytesToWrite: Int) = write(address.toLong(), data, bytesToWrite)
    fun write(address: Long, data: Memory, bytesToWrite: Int = data.size().toInt())
            = write(address, data as Pointer, bytesToWrite)
    fun write(address: Int, data: Memory, bytesToWrite: Int = data.size().toInt())
            = write(address.toLong(), data, bytesToWrite)
    fun write(address: Long, struct: Struct, bytesToWrite: Int = struct.size())
            = write(address, struct.pointer, bytesToWrite)
    fun write(address: Int, struct: Struct, bytesToWrite: Int = struct.size())
            = write(address.toLong(), struct, bytesToWrite)
    // ...
}  此接口适用于address的Long,但出于某些原因也接受Int。我认为你应该偷看一个(E.I. Long),并让消费者担心如何将Int转换为Long。这不是API的责任。此外,如果消费者使用的应用程序接口使用address的Long,他通常也会使用Long来操作他那端的地址。这简化了接口,节省了Int转Long和反向转换的时间,提高了性能。
https://stackoverflow.com/questions/38549247
复制相似问题