The main example which springs to mind is io.Reader.Read 
<https://pkg.go.dev/io#Reader> which may return a non-zero number of read 
bytes *and* and error from the same call. Because this is so unusual, it is 
carefully emphasised in the docs:

*Callers should always process the n > 0 bytes returned before considering 
the error err. Doing so correctly handles I/O errors that happen after 
reading some bytes and also both of the allowed EOF behaviors.*
Anyway: the point here is that if a function returns (ptr, err) then in the 
case err = nil it will conventionally guarantee that ptr is valid, so the 
caller doesn't need to check ptr != nil before dereferencing it. But if err 
!= nil, no such guarantee is implied, and it's highly unlikely that you 
could safely deference ptr. That convention is not in the spec, but 
dereferencing a nil pointer causing a panic is:

*the pointer indirection *x denotes the variable 
<https://go.dev/ref/spec#Variables> of type T pointed to by x. If x is nil, 
an attempt to evaluate *x will cause a run-time panic 
<https://go.dev/ref/spec#Run_time_panics>.*

On Sunday, 6 July 2025 at 07:05:12 UTC+1 Kurtis Rader wrote:

> On Sat, Jul 5, 2025 at 9:19 PM Ge <everg...@gmail.com> wrote:
>
>> Thanks Ian and Dominik for the tips. I have checked the issue 72860 and 
>> found randall77 posted a comment that
>> I couldn't confirm from golang spec(go.dev/ref/spec):
>>
>> //https://github.com/golang/go/issues/72860#issuecomment-2734549770
>> ```
>>
>> Where f returns a pointer and an error. f expects its callers to only 
>> use the ptr result if the error is nil. And in particular, f returns a 
>> nil pointer whenever it returns a non-nil error.
>>
>> This code is incorrect, in that it dereferences the ptr result before 
>> checking the error. The Go spec says that it should nil pointer panic if 
>> f returns a nil pointer and non-nil error. 
>> ```
>>
>> I did a search in whole spec and did't find any descriptions about it.
>> From my understanding, `v, err := f()` is like `v1, v2 := f()` from 
>> compiler's view, 
>> checking error is user code's business logic and couldn't be assumed by 
>> compiler.
>> If it's defined in spec, what about variants like `a, b, err := f()` or 
>> `a, b, err1, err2 := f()`?
>>
>
> No, it is not defined in the spec. For the very reasons you mention (and 
> probably others). But I would argue that commonsense suggests that unless a 
> function explicitly says a returned non-error pointer is useful (i.e., 
> non-nil) when an error is returned you should assume that pointer is likely 
> to be nil if an error is indicated. Ideally this would be explicit in the 
> documentation of every function that returns an error and non-error 
> pointer. However, in the absence of the documentation stating that the 
> non-error pointer value is useful if an error is indicated it seems 
> reasonable to assume that pointer is not useful; even if it isn't nil. Even 
> a non-pointer return value is unlikely to be meaningful if an error was 
> indicated unless explicitly documented. If the called function returns the 
> "zero value" when it also returns an error indicator what does it mean to 
> ignore the error and use the "zero value"? That's obviously context 
> dependent but it is unlikely, in my experience, to ignore the error and use 
> the returned "zero value".
>  
> -- 
> Kurtis Rader
> Caretaker of the exceptional canines Junior and Hank
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/82186037-d56f-44e1-9a98-6b8cf6856ef6n%40googlegroups.com.

Reply via email to