today's rust mystery section 4.9 of rust programming language, first edition. example of references , borrowing has example:
fn main() { fn sum_vec(v: &vec<i32>) -> i32 { return v.iter().fold(0, |a, &b| + b); } fn foo(v1: &vec<i32>) -> i32 { sum_vec(v1); } let v1 = vec![1, 2, 3]; let answer = foo(&v1); println!("{}", answer); } that seems reasonable. prints "6", you'd expect if v of sum_vec c++ reference; it's name memory location, vector v1 defined in main().
then replaced body of sum_vec this:
fn sum_vec(v: &vec<i32>) -> i32 { return (*v).iter().fold(0, |a, &b| + b); } it compiled , worked expected. okay, that's not… entirely crazy. compiler trying make life easier, that. confusing, have memorize specific tic of language, not entirely crazy. tried:
fn sum_vec(v: &vec<i32>) -> i32 { return (**v).iter().fold(0, |a, &b| + b); } it still worked! hell?
fn sum_vec(v: &vec<i32>) -> i32 { return (***v).iter().fold(0, |a, &b| + b); } type [i32] cannot dereferenced. oh, thank god, makes sense. have expected 2 iterations earlier!
references in rust aren't c++ "names place in memory," are they? they're not pointers either, , rules them seem either esoteric or highly ad-hoc. happening such reference, pointer, , pointer-to-a-pointer work equally here?
the rules not ad-hoc nor esoteric. inspect type of v , it's various dereferences:
fn sum_vec(v: &vec<i32>) { let () = v; } you'll get:
v->&std::vec::vec<i32>*v->std::vec::vec<i32>**v->[i32]
the first dereference understand. second dereference deref trait. vec<t> dereferences [t].
when performing method lookup, there's straight-forward set of rules:
- if type has method, use , exit lookup.
- if reference type has method, use , exit lookup.
- if type can dereferenced, so, return step 1.
- else lookup fails.
references in rust aren't c++ "names place in memory,"
they absolutely names place in memory. in fact, compile down same c / c++ pointer know.
Comments
Post a Comment