我開始學習階。不知道是否有人有更好的方法來以更實用的方式重寫下面的代碼。我知道必須有一個。更優雅的Scala代碼
val buf = ((addr>>24)&0xff) + "." + ((addr>>16)&0xff) + "." + ((addr>>8)&0xff) + "." + ((addr)&0xff)
我開始學習階。不知道是否有人有更好的方法來以更實用的方式重寫下面的代碼。我知道必須有一個。更優雅的Scala代碼
val buf = ((addr>>24)&0xff) + "." + ((addr>>16)&0xff) + "." + ((addr>>8)&0xff) + "." + ((addr)&0xff)
這將生成Range(24, 16, 8, 0)
與(24 to 0 by -8)
然後函數addr >> _ & 0xff
適用於使用map
每個號碼。最後,映射的Range
的數字與.
「加入」來創建一個字符串。
該映射比使用+
運算符更具功能性,但剩下的只是語法糖和對mkString
的庫調用。
val addr = 1024
val buf = (24 to 0 by -8).map(addr >> _ & 0xff).mkString(".")
buf: java.lang.String = 0.0.4.0
val buf = List(24,16,8,0).map(addr >> _).map(_ & 0xff).mkString(".")
這是我會怎麼做,使用Scala的著名「_」操作類似於布賴恩的答案,但有值的簡短列表和兩個簡單的地圖()方法。偉大的問題!
有些人會發現對理解一點點可讀:
(for (pos <- 24 to 0 by -8) yield addr >> pos & 0xff) mkString "."
的優點是輸入 - 可以是整數
// trick
implicit class When[F](fun: F) {
def when(cond: F => Boolean)(tail: F => F) = if (cond(fun)) tail(fun) else fun
}
// actual one-liner
12345678.toHexString.when(1 to 8 contains _.length % 8)
(s => "0" * (8 - s.length % 8) + s).reverse.grouped(2).map
(Integer.parseInt(_, 16)).toList.reverse.mkString(".")
// 0.203.22.228
// a very big IPv7
BigInt("123456789").toString(16).when(1 to 8 contains _.length % 8)
(s => "0" * (8 - s.length % 8) + s).reverse.grouped(2).map
(Integer.parseInt(_, 16)).toList.reverse.mkString(".")
// 0.0.0.96.27.228.249.24.242.99.198.83
編輯
解釋的任何數量的因爲降價。 implicit class When
可以只是一個庫類,它工作在2.10
並允許在呼叫鏈有條件地執行某些功能。我沒有衡量表現,也不在意,因爲一個例子本身就是對可能,優雅與否的例證。
你轉換成字符串,然後再次解析。然後再到一個字符串。非常低效。 –
這是一個缺點=) – idonnie
這不會產生相同的行爲(即帶前導零),所以它可能不是OP想要的東西,它甚至不發出警告,它不相同的方式工作(錯誤等待即將發生)。 –
你不需要'_'此:'名單(24,16,8,0).MAP(地址>>)地圖(0xFF的&)mkString( 「」)' –
@KimStebel:是啊,但由於後綴運算符,你會在2.10中得到警告(正如我的觀點,因爲它們看起來像尤達條件)。 – sschaef
@sschaef:我知道,我感謝斯卡拉團隊'-language:_' –