2016-07-24 4 views
1

多くの場合、Kotlinは非リテラルに対して暗黙的な変換を行わないので、自分自身が数値型のオーバーロードをたくさん作成していることがよくあります。その結果、膨大な量の重複した過負荷機能が発生し、これは何トンものボイラープレートになります。Kotlin:番号のオーバーロードをクリーンアップする方法はありますか?

私はこれをやっている痛みの例をここで見ることができます:https://github.com/Jire/Arrowhead/blob/master/src/main/kotlin/org/jire/arrowhead/Source.kt

私は暗黙の型変換がバグを引き起こす可能性があります理由を理解し、私はほとんどのケースで考え、特にByte -> Intのような「拡大」の変換のためにとInt -> Longデータが失われていない方が良い方法があるはずです。

だから私の質問はどうやってこれに対処するのですか?この問題を解決する創造的な方法はありますか?

+0

ところで、なぜJNAの代わりにJNRを使用しないのですか? JNRははるかに高速です。 – SerCe

+0

@ SerCe直接マッピングされたJNAに対するパフォーマンステストでは、パフォーマンスの向上はほとんどなく、パフォーマンスの低下が見られます。 – Jire

答えて

2

質問に答える: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) 

    // ... 
} 

このAPIはaddressためLongで動作しますが、また、何らかの理由でInt受け付けます。私はあなたが1つ(e.i Long)を覗いて、消費者にIntLongに変換することを心配させるべきだと思います。これはAPIの責任ではありません。また、消費者がにLongを使用するAPIを使用している場合、彼は通常Longを使用してその側のアドレスも操作します。これにより、APIが簡素化され、IntLongとバックコンバージョンが節約され、パフォーマンスが向上します。

+0

私のケースパフォーマンスは非常に重要です。関数は毎秒何千回も呼び出される必要があります。番号は知っておくべきことです! – Jire

+0

2秒間に数百万回もの呼び出しがありません。私はあなたのプログラムを測定し、あなたのプログラムを測定し、ボクシングがあれば注目すべき違いがあるかどうかを調べるアドバイス – voddan

関連する問題