循环的应变量声明总是放在外面?放在、变量、声明

2023-09-04 00:53:21 作者:爱,又何必多问

它是更好地宣布在循环中使用的变量在循环外部而不是内部?有时候,我看到一个变量在循环内声明的例子。这是否有效地使程序分配内存的循环运行一个新的变量每次?或者是.NET足够聪明,知道它确实是同一个变量。

例如看到下面的code this回答。

 公共静态无效CopyStream(流输入,流输出)
{
    byte []的缓冲区=新的字节[32768]
    而(真)
    {
        INT读= input.Read(缓冲,0,buffer.Length);
        如果(读< = 0)
            返回;
        output.Write(缓冲,0,读);
    }
}
 

请问这个修改后的版本进行任何比较有效?

 公共静态无效CopyStream(流输入,流输出)
{
    INT读取; //外环线
    byte []的缓冲区=新的字节[32768]
    而(真)
    {
        读= input.Read(缓冲,0,buffer.Length);
        如果(读< = 0)
            返回;
        output.Write(缓冲,0,读);
    }
}
 
九,作用域

解决方案

没有,它不会是更有效的。不过,我把它改写这种方式恰好在循环外部声明也无妨:

 字节[]缓冲区=新的字节[32768]
INT读取;
而((读取= input.Read(缓冲液,0,buffer.Length))大于0)
{
    output.Write(缓冲,0,读);
}
 

我不是一般使用条件下的副作用的粉丝,但有效的方法是给你们两个比特的数据:无论您是否已经到达流的末尾,有多少你已经读过。 while循环现在又说,虽然我们已经成功地读取一些数据...复制它。

这是一个有点像使用 int.TryParse

 如果(int.TryParse(文字,超时值))
{
    //使用价值
}
 

同样,你正在使用调用中的条件方法的副作用。正如我说的,我不作习惯了这样的除了的这种特殊的模式,当你处理一个方法返回数据的两位。

同样的事情出现读取行的的TextReader

 串线;
而((行= reader.ReadLine())!= NULL)
{
    ...
}
 

要回到你原来的问题:如果一个变量是要在一个循环的每一次迭代进行初始化的和的它只是循环体中使用,我几乎总是将它声明内循环。这里的一个小的例外是,如果变量被抓获的匿名函数 - 在这一点上它会让行为上的差异,我挑的形式给了我所期望的行为......但是这几乎总是声明里形成反正。

编辑:当涉及到作用域,在code以上确实离开变量在更大范围上比它需要......但我相信,这使循环更加清晰。您可以通过引入新的范围,如果你愿意永远解决这个问题:

  {
    INT读取;
    而 (...)
    {
    }
}
 

Is it better to declare a variable used in a loop outside of the loop rather then inside? Sometimes I see examples where a variable is declared inside the loop. Does this effectively cause the program to allocate memory for a new variable each time the loop runs? Or is .NET smart enough to know that it's really the same variable.

For example see the code below from this answer.

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    while (true)
    {
        int read = input.Read (buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write (buffer, 0, read);
    }
}

Would this modified version be any more efficent?

public static void CopyStream(Stream input, Stream output)
{
    int read; //OUTSIDE LOOP
    byte[] buffer = new byte[32768];
    while (true)
    {
        read = input.Read (buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write (buffer, 0, read);
    }
}

解决方案

No, it wouldn't be more efficient. However, I'd rewrite it this way which happens to declare it outside the loop anyway:

byte[] buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
    output.Write(buffer, 0, read);
}

I'm not generally a fan of using side-effects in conditions, but effectively the Read method is giving you two bits of data: whether or not you've reached the end of the stream, and how much you've read. The while loop is now saying, "While we've managed to read some data... copy it."

It's a little bit like using int.TryParse:

if (int.TryParse(text, out value))
{
    // Use value
}

Again you're using a side-effect of calling the method in the condition. As I say, I don't make a habit out of doing this except for this particular pattern, when you're dealing with a method returning two bits of data.

The same thing comes up reading lines from a TextReader:

string line;
while ((line = reader.ReadLine()) != null)
{
    ...
}

To go back to your original question: if a variable is going to be initialized in every iteration of a loop and it's only used within the body of the loop, I'd almost always declare it within the loop. One minor exception here is if the variable is being captured by an anonymous function - at that point it will make a difference in behaviour, and I'd pick whichever form gave me the desired behaviour... but that's almost always the "declare inside" form anyway.

EDIT: When it comes to scoping, the code above does indeed leave the variable in a larger scope than it needs to be... but I believe it makes the loop clearer. You can always address this by introducing a new scope if you care to:

{
    int read;
    while (...)
    {
    }
}

 
精彩推荐
图片推荐