> There's a race condition between the if and do something which invalidates the programmers world view (someone can delete the file between these two statements). And this is an exceptional situation the program has to deal with.
It's not an exceptional situation. It's a bug in your program. And it's not lazy to open() and check for existence. It's actually the _only_ sane way to check that the file exists, if you plan to open it.
> Error codes may tell the programmer this, but it is quite likely that the programmer will just ignore it, because "I've already checked that it exists - what could possibly go wrong?"
The following code is obviously wrong because of the race condition you mention. Nobody in their right mind would write code like this.
if exists(file) {
f = open(file)
// do something with f
} else {
// handle "file not found" case
}
This code is correct, to some degree:
try {
f = open(file)
// do something with f
} catch (file not found error) {
// handle "file not found" case
}
As is this Go code:
f, err := os.Open(file)
if os.IsNotExist(err) {
// handle "file not found" case
} else if err != nil {
// handle any other error that might arise
}
// do something with f
The thing is, the above code is not me being extra careful about checking errors. It's just bog standard Go code. Checking error values is the only way to write even half-decent Go code, so everyone does it all the time.
No reasonable programmer would write Go code like this:
_, err := os.Stat(file)
if err != nil {
// handle "file not found" case
} else {
f, _ := os.Open(file)
// do something with f
// (or explode if file doesn't exist)
}
To my Go programmer eyes, the underscore (where I'm ignoring the error) in the os.Open line sticks out like a sore thumb. You wouldn't write it, and when reading you would certainly notice it as bad code (or at the very least extraordinary code).
It's not an exceptional situation. It's a bug in your program. And it's not lazy to open() and check for existence. It's actually the _only_ sane way to check that the file exists, if you plan to open it.
> Error codes may tell the programmer this, but it is quite likely that the programmer will just ignore it, because "I've already checked that it exists - what could possibly go wrong?"
The following code is obviously wrong because of the race condition you mention. Nobody in their right mind would write code like this.
This code is correct, to some degree: As is this Go code: The thing is, the above code is not me being extra careful about checking errors. It's just bog standard Go code. Checking error values is the only way to write even half-decent Go code, so everyone does it all the time.No reasonable programmer would write Go code like this:
To my Go programmer eyes, the underscore (where I'm ignoring the error) in the os.Open line sticks out like a sore thumb. You wouldn't write it, and when reading you would certainly notice it as bad code (or at the very least extraordinary code).