Why use while over if in single wordpress posts?

As the WordPress Codex for have_posts points out:

As a side effect, have_posts starts, steps through, or resets The Loop. At the end of the loop, have_posts returns 0 after calling rewind_posts.

Looking at the source as it stands today: along with calling rewind_posts() it also fires the loop_end action (which plugins may rely upon) as well as set a flag so in_the_loop() correctly returns false afterwards.

So calling have_posts() on each iteration does more than just return a Boolean. I wouldn’t lean too much on the specifics of the source because that’s a moving object. It’s enough to understand that there are other housekeeping tasks performed when you call have_posts() until it returns false and you’re less likely to introduce subtle interoperability issues if you use it that way even when there is only a single post involved.