3

我开始学习scala。想知道是否有人有更好的方法以更实用的方式重写下面的代码。我知道一定有一个。

val buf = ((addr>>24)&0xff) + "." + ((addr>>16)&0xff) + "." + ((addr>>8)&0xff) + "." + ((addr)&0xff)
4

4 回答 4

11

这会生成Range(24, 16, 8, 0)with (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
于 2013-01-03T05:30:03.620 回答
3
val buf = List(24,16,8,0).map(addr >> _).map(_ & 0xff).mkString(".")

这是我的做法,类似于布赖恩的回答,但有一个简短的值列表和两个使用 Scala 著名的 '_' 运算符的简单 map() 方法。好问题!

于 2013-01-03T06:25:22.060 回答
2

有些人会发现 for 理解更具可读性:

(for (pos <- 24 to 0 by -8) yield addr >> pos & 0xff) mkString "."
于 2013-01-03T06:43:51.773 回答
-2

优点是输入 - 可以是任意数量的整数

// 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("123456789012345678901").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调用链中工作并允许有条件地执行一些函数。我没有衡量性能,也不在乎,因为一个例子本身就是为了说明什么是可能的,优雅与否。

于 2013-01-03T09:47:04.297 回答