Kotlin:有没有办法清理数量过载?

通常我发现自己为数字types创建了很多重载,因为Kotlin不会为非文字进行隐式转换。 这导致了大量的重复过载函数,这是吨和吨的样板。

我可以看到一个这样的痛苦的例子: https : //github.com/Jire/Arrowhead/blob/master/src/main/kotlin/org/jire/arrowhead/Source.kt

我明白隐式转换可能导致错误的原因,但是我认为在大多数情况下,尤其是对于像Byte -> IntInt -> Long这样的数据没有丢失的“扩展”转换,应该有更好的方法。

所以…我的问题是你如何处理这个? 有没有创造性的方法来解决这个问题?

回答你的问题:你可以使用一个带有Number的通用函数。 那么它会接受任何数字的子types。 然后,您可以将该值转换为任何其他数字types:

 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) // ... } 

此API与Long for address ,但由于某种原因也接受Int 。 我想你应该偷看一个(ei Long ),让消费者担心把Int转换成Long 。 这不是API的责任。 另外,如果一个消费者使用一个使用Longaddress的API,他通常也会使用Long来处理他的地址。 这简化了API,并将IntLong和Back转换保存起来,从而提高了性能。