On Sun, Sep 19, 2021 at 5:19 PM roger peppe <rogpe...@gmail.com> wrote:

> In some ways, the existing API is arguably more ergonomic than the
> originally proposed generic version, as it's possible to use `errors.As` in
> a switch statement (eg to test several possible types of error) which isn't
> possible with the multi-return `As` variant.
>

Hmm, that's a good point.
However, the main reason I like the two-return-value version more is that
you can use it like a normal type-assertion in an if-statement's init
section.


> A minor variant of the existing API could be:
>
> ```
> func As[E error](err error, asErr *E) bool
> ```
> which makes the API a little clearer without changing the usage. Sadly we
> can't make that change without breaking compatibility.
>
> Unfortunately, in order to use this proposed version, you still need to
pre-declare the variables for each type before the switch/case.
I've honestly found it more ergonomic to use a if/else if/ block rather
than a switch/case because it lets me contain the scope of these variables
anyway.

I suppose a simple wrapper that can be used with type-assertions inside a
switch/case block would be:
```
func AsBool[E error](err error, asErr error) bool {
    ae, ok := As[E](err)
    if ok {
         asErr = ae
    }
    return ok
}
```
(this would definitely need a better name)

Then you'd be able to almost treat your switch/case like a type-switch
without needing to pre-declare a variable for every case.

```
var asErr error
switch {
   case errors.AsBool[*os.PathError](err, &asErr):
       fmt.Printf("Path Error! ae: %v", asErr.(*os.PathError))
   case errors.AsBool[syscall.Errno](err, &asErr):
       fmt.Printf("ae: %d", asErr.(syscall.Errno))
}
```

However, I think it would be nicer to use the (originally proposed)
two-return errors.As with if/else if.

```
if pe, ok := errors.As[*os.PathError](err); ok {
    fmt.Printf("Path Error: %v", pe)
} else if en, ok := errors.As[syscall.Errno](err); ok {
    fmt.Printf("errno %[1]d: %[1]s", en)
}
```

Since it looks like the dev.typeparams branch has been merged into master,
I was just thinking about how we'd add the two-return-value/generic version
of As to the errors package (for go 1.18).
Given that the original proposal's code works pretty much as-is, I think
the biggest barrier would be a good name. (given that As is already taken)

>
> On Sun, 19 Sep 2021, 21:15 David Finkel, <david.fin...@gmail.com> wrote:
>
>>
>>
>>
>> On Sun, Sep 19, 2021 at 4:02 PM David Finkel <david.fin...@gmail.com>
>> wrote:
>>
>>> You might be interested in the original draft proposal for errors.As:
>>>
>>> https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md#the-is-and-as-functions
>>>
>>> In particular, it originally specified that errors.As would take a
>>> type-parameter. (the version of generics that was proposed concurrently
>>> with that proposal was not accepted so they had to go with the current
>>> (clunkier) interface).
>>>
>>
>> Hmm, actually, the code in that proposal for the generic version of
>> errors.As works almost unchanged:
>> https://go2goplay.golang.org/p/ddPDlk00Cbl (I just had to change the
>> type-parameter syntax)
>>
>>
>>> On Sun, Sep 19, 2021 at 5:33 AM Haddock <ffm2...@web.de> wrote:
>>>
>>>>
>>>> I like the way error handling is done in the xerror package. Things
>>>> become more concise, but remain very easy to read and understand as in
>>>> plain Go errorhandling.
>>>>
>>>> Here is the example of how to use xerror.As:
>>>>
>>>> _, err := os.Open("non-existing")
>>>>     if err != nil {
>>>>         var pathError *os.PathError
>>>>         if xerrors.As(err, &pathError) {
>>>>             fmt.Println("Failed at path:", pathError.Path)
>>>>         }
>>>>     }
>>>>
>>>> My idea is to make this even shorter like this:
>>>>
>>>> _, err := os.Open("non-existing")
>>>> myerrors.As(err, os.PathError) {
>>>>      pathError -> fmt.Println("Failed at path:", pathError.Path)
>>>> }
>>>>
>>>> Think something like that has so far not been suggested. That's why I
>>>> thought it is justified to drop comment.
>>>>
>>>> myerrors.As would also do the check if err is nil. The code in my
>>>> sample is not valid Go code, I know. It is only pseudo code to show the
>>>> idea.
>>>>
>>>> --
>>>> 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 on the web visit
>>>> https://groups.google.com/d/msgid/golang-nuts/629e6763-36a9-4d7d-991c-fd71dd384d0en%40googlegroups.com
>>>> <https://groups.google.com/d/msgid/golang-nuts/629e6763-36a9-4d7d-991c-fd71dd384d0en%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>> --
>> 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 on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CANrC0BgsVSo0hv5UtTi%3DVXZYZODys1H-kvB63o2B3UThBMnfxQ%40mail.gmail.com
>> <https://groups.google.com/d/msgid/golang-nuts/CANrC0BgsVSo0hv5UtTi%3DVXZYZODys1H-kvB63o2B3UThBMnfxQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
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 on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BhBBtJWPcWQQrQTYN45eVrPWBp%2BggtCTsvL1ez5vvuf6Q%40mail.gmail.com.

Reply via email to