我开始学习阶。不知道是否有人有更好的方法来以更实用的方式重写下面的代码。我知道必须有一个。更优雅的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:_' –