#why the reference is required here ?
115 messages · Page 1 of 1 (latest)
func As(err error, target any) bool
As finds the first error in err's tree that matches target, and if one is found, sets target to that error value and returns true. Otherwise, it returns false....
More documentation omitted
the "and if one is found, sets target to that error value" is why a pointer is required
ok let me check again
that is true
!go
package main
import ("fmt";"errors";"os")
func main() {
var a error = errors.New("error a")
var b *os.PathError
tst := errors.As(a, &b)
if tst == true {
fmt.Println(a)
fmt.Println(b)
}else {
fmt.Println(tst)
}
}
i've seen you discussing this recently, so tl;dr:
errors.Is checks if any error in the wrapped error is equal to a certain error value
errors.As checks if any error in the wrapped error has a certain type (and gives you the value of that type if so)
value vs type
yes it was really confusing i spent so much time trying to figure it out
and finally i did
is just checks if an error referencing to another error or they are separete errors
package main
import ("fmt";"errors")
func main() {
var one error = errors.New("error one")
var two *error = &one
fmt.Println(errors.Is(one, *two))
}
am i correct about is ?
it's not quite "referencing"
from the docs:
An error is considered to match a target if it is equal to that target or if it implements a method Is(error) bool such that Is(target) returns true.
so either equal as determined by == or by an Is method on the error type
how equal ?
var one error = error
var two error = error
it is false
but if
var one error = error
var two error = one
it is true
from the spec:
Interface types that are not type parameters are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.
remember that errors.New is not the only way to make an error
anything that implements Error() string is an error
you could have an integer type be an error, then having two completely unrelated assignments of that be equal
i see
is using is the same as using == ?
i really didn't understand what u said
it checks if the two errors are equal by ==
if so, it returns true
if not, it checks for an Is method and calls that
so is uses == ?
yes, that is what i said
so basically it checks the memory address of both errors
no, it doesn't
again
package main
import ("fmt";"errors")
func main() {
var one error = errors.New("error one")
var two *error = &one
fmt.Println(&one)
fmt.Println(two)
}
0xc000022070
0xc000022070
two equal errors having the same address does not mean that non-equal addresses cannot be equal
you proved one direction, not the other
let me try again
package main
import ("fmt";"errors";"os")
func main() {
var one *os.LinkError
var two *os.PathError
fmt.Println(errors.Is(one, two))
}
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x30 pc=0x4117e0]
see
!go
package main
type CustomError int
func (CustomError) Error() string {
return "CustomError"
}
func main() {
one := CustomError(5)
two := CustomError(5)
fmt.Printf("%p\n", &one)
fmt.Printf("%p\n", &two)
fmt.Println(errors.Is(one, two))
}
it compares the memory addresses
ok let me try
i would really suggest not knee-jerking to saying the other person is wrong when you're actually wrong
it's incessant
try having an open mind
it's like you think you're in some sort of argument with everyone 😂 we're just trying to help
0xc00000a0b8
0xc00000a0d0
true
but it doesn't prove anything both variables use the same type which the same address
hhh nono
types don't have addresses
i apologies for any inconviniece
they're two variables with two different memory addresses, and somehow == is still true
it must mean they're not comparing memory addresses 🙂
again
ok let me try harder brother
if the dynamic type of an interface is a pointer, yes, you would be comparing memory addresses
but not all errrors have a dynamic type of a pointer
in particular, the return type of errors.New is a pointer under the hood, yes
but errors.New is not the only way to get an error value
package main
// is :
// as :
import ("fmt";"errors")
func main() {
var one error = errors.New("error happened")
var address_one *error = &one
var two error = errors.New("error happened")
var address_two *error = &two
fmt.Println(address_one)
fmt.Println(address_two)
fmt.Println(errors.Is(one, two))
}
0xc00008a030
0xc00008a050
false
sure, but the fact that two errors with different addresses returns false here does not mean that all errors with different addresses return false
you've got your logic backwards here
what i want to say is if an error uses the same error addresses of another error it is for sure true other than this it is false which means is compares the memory address of two error types and checks if they are sharing the same memory address
i'm not so sure why you're so fixated on addresses
it's not inherent to comparing interfaces
== is simply applied on the dynamic value
could the dynamic value be a pointer? sure, but it could also be a string, integer, etc.
no, it is all about runtime
that's what interfaces are
the dynamic, rather than static, type
i'm really not so sure you understand, given this conversation so far
ok let's exclude the memory addresses
if two different variables have the same error type
should it be true or false ?
of course false
do u agree ?
no, if they have the same type, then an equality check needs to happen
what would the result of is be ?
there's not enough information, an equality check needs to happen
you have two errors of the same type that are the same or different
package main
// is :
// as :
import ("fmt";"errors")
func main() {
var one error = errors.New("error happened")
var two error = errors.New("error happened")
fmt.Println(errors.Is(one, two))
fmt.Println(one == two)
}```
false
false
remember this
that is wrong
u are showing me the memory addresses of two different variables not errors
they are error variables
ok, how about ```go
package main
import (
"errors"
"fmt"
)
type CustomError int
func (CustomError) Error() string {
return "CustomError"
}
func main() {
var one error = CustomError(5)
var two error = CustomError(5)
fmt.Printf("%p\n", &one)
fmt.Printf("%p\n", &two)
fmt.Println(errors.Is(one, two))
}
spoiler alert: the answer is the same
you seem to be conflating the fact that dynamic values can themselves be pointers
but they need not be
i already explained that here
utterly contemptible conduct
u really don't know how memory addresses work !!!
anyways