在 Scala 中编写 read-while 循环的正确方法是什么?
在 Scala 中编写标准 read-while 循环的“正确”是什么?我所说的“正确”是指以类似 Scala 的方式编写,而不是类似 Java 的方式。
这是我在 Java 中的代码:
MessageDigest md = MessageDigest.getInstance( "MD5" );
InputStream input = new FileInputStream( "file" );
byte[] buffer = new byte[1024];
int readLen;
while( ( readLen = input.read( buffer ) ) != -1 )
md.update( buffer, 0, readLen );
return md.digest();
这是我在 Scala 中的代码:
val md = MessageDigest.getInstance( hashInfo.algorithm )
val input = new FileInputStream( "file" )
val buffer = new Array[ Byte ]( 1024 )
var readLen = 0
while( readLen != -1 )
{
readLen = input.read( buffer )
if( readLen != -1 )
md.update( buffer, 0, readLen )
}
md.digest
Scala 代码是正确的并且可以工作,但感觉非常不 Scala 风格。其一,它是 Java 代码的直译,没有利用 Scala 的任何优点。而且它实际上比 Java 代码还要长!我真的感觉自己失去了一些东西,但又想不起来到底是什么。
我对 Scala 相当陌生,所以我问这个问题是为了避免陷入在 Scala 中编写 Java 风格代码的陷阱。我对解决此类问题的 Scala 方法更感兴趣,而不是 Scala API 可能提供的用于散列文件的任何特定帮助程序方法。
(对于我在这个问题中使用的临时 Scala 形容词,我提前表示歉意。)
What is the "proper" of writing the standard read-while loop in Scala? By proper I mean written in a Scala-like way as opposed to a Java-like way.
Here is the code I have in Java:
MessageDigest md = MessageDigest.getInstance( "MD5" );
InputStream input = new FileInputStream( "file" );
byte[] buffer = new byte[1024];
int readLen;
while( ( readLen = input.read( buffer ) ) != -1 )
md.update( buffer, 0, readLen );
return md.digest();
Here is the code I have in Scala:
val md = MessageDigest.getInstance( hashInfo.algorithm )
val input = new FileInputStream( "file" )
val buffer = new Array[ Byte ]( 1024 )
var readLen = 0
while( readLen != -1 )
{
readLen = input.read( buffer )
if( readLen != -1 )
md.update( buffer, 0, readLen )
}
md.digest
The Scala code is correct and works, but feels very un-Scala-ish. For one it is a literal translation of the Java code, taking advantage of none of the advantages of Scala. Further it is actually longer than the Java code! I really feel like I'm missing something, but I can't figure out what.
I'm fairly new to Scala, and so I'm asking the question to avoid falling into the pitfall of writing Java-style code in Scala. I'm more interested in the Scala way to solve this kind of problem than in any specific helper method that might be provided by the Scala API to hash a file.
(I apologize in advance for my ad hoc Scala adjectives throughout this question.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据 Rex 的帖子,他提到:
您应该替换 var readLen + while {...} 行,它会产生相同的结果。
正如 Rex 提到的,它适用于 scala 2.8。
Based on Rex's post that he mentioned:
You should replace the var readLen + while {...} lines with it, it produces the same result.
As Rex mentioned, it works with scala 2.8.
Rex Kerr 在他的评论中建议如下:
关键是
Stream.continually
。它获取一个不断求值的表达式,创建一个求值表达式的无限Stream
。takeWhile
是while
条件的转换。foreach
是while
循环的主体。What Rex Kerr suggests in his comment is the following:
The key is the
Stream.continually
. It gets an expression which is evaluated continually, creating an infiniteStream
of the evaluated expression. ThetakeWhile
is the translation from thewhile
-condition. Theforeach
is the body of thewhile
-loop.柯里化函数怎么样?您的 11 行 Scala 代码变为:
第 3 行的
iterateStream
函数,您可以将其添加到库中:丑陋的重复代码(读取输入的位置)最终出现在库中,经过充分测试并且远离程序员。我觉得第一段代码比 Iterator.continually 解决方案简单。
What about a curried function? You 11 lines of Scala code become:
The
iterateStream
function on line 3, which you could add to a library is:The ugly duplicated code (where the input is read) ends up in the library, well tested and hidden away from the programmer. I feel that the first block of code is less complex than the
Iterator.continually
solution.