3 ms·
it does not resolve the problem. you would need to check "is this value optional?" and unpacking everywhere. this is what this article saying. you can do unpa
by 5701652400 4mo ago
it does not resolve the problem.
you would need to check "is this value optional?" and unpacking everywhere.
this is what this article saying.
you can do unpacking/nil-checks at the root or later when it happened.
with rust you have 2x more ways to shoot yourself in the foot.
- BoardsOfCanada 4mo agoObviously, in his example it would be RateLimiter not Option<RateLimiter>, so no check necessary.
- 5701652400 4mo agoyou still need to unpack that option somewhere.
- Someone 4mo ago_If_ you start out with an optional, and even then only once in the code path.
- guilhas 4mo agoI think the author can propagate RateLimiter instead of *RateLimiter, making it exactly the same
- diarrhea 4mo agoNo, because RateLimiter is then copied on passing it around (pass by value). That is problematic for two reasons: it might be a large type, so copying might be expensive. Second, more likely, it might violate invariants in your domain. For a rate limiter, this might mean accidentally copying around some internal state like a mutex, which then exists n times instead of 1 time, which can represent a problem (e.g. if you want to internally limit whole-app concurrency toward Redis).
- guilhas 4mo agoYou can see the code Clearly is not large. Second the child object is a pointer so does not violate anything And if if if... I am sure we can look for new constraints in any language
- bestouff 4mo agoYou check and unpack once, then the rest of the "positive" codepath can use the reference without fearing null. I fail to see how Rust would offer twice as many ways to shoot yourself in the foot ; this is a rather safe and picky language.
- 5701652400 4mo agotrue, "non-nil pointers"/references will help here to avoid nil checks. also true, if you have optional you still need to unpack it somwhere, and your nil checks become unpacking statements. delayed conditionals and delegation to callsites far from offending code (what author says) is still present. and if you also have pointers, then you can do Optional<Pointer>.. and now you have to option unpakcing + nil checks. 2x more problems.
- tialaramex 4mo agoIf you have an actual pointer type *mut P then Option<*mut P> might be None or it might be Some(null_pointer) or Some(other_pointer) that's not 2x more problems it's just a representation of a more complicated scenario - we may or may not have a pointer and, if we do have a pointer that might be null. We'd presumably have done this because we need to distinguish those cases. If you actually mean Option<NonNull<P>> you should write that, now we're saying this is either a non-null pointer or it's nothing. Often though you want Option<&P> either a reference or nothing, or you actually did mean a raw pointer *mut P and you're going to handle scenarios where it is null or whatever. Edited: Fix asterisks
- K0nserv 4mo ago> with rust you have 2x more ways to shoot yourself in the foot. The checking isn't how you shoot yourself in the foot, it's the absence of checking. Rust doesn't allow you to forget to check. This entire class of problems just disappears in Rust. In this if the code needs a non-null redis client to work you take `RedisClient` not `Option<RedisClient>`.
- deleted 4mo ago[deleted]
- 5701652400 4mo agoyes that is correct. tbh in Go for service structs that what you would do as well. use value receivers for such things. and inject dependencies as interfaces. so pointers not immediately visible and it is just type RedisClient interface in your field/arg.