> fn borrow1<'a>(&'a self) -> &'a int {
> match (self) {
> // error: mismatched types: expected `&'a int` but found `~int`
> // (expected &-ptr but found ~-ptr)
> &Foo(ref v) => *v
> }
> }
This doesn't work because the local variable v has type &~int, when
you dereference this you get something of type ~int which if you load
is a move so you're not allowed to do that. Additionally, the return
type wants &int when you're giving it ~int
> fn borrow2<'a>(&'a self) -> &'a int {
> match (self) {
> // WORKS
> &Foo(ref v) => &**v
> }
> }
This works because you're going from &~int => ~int => int => &int via
the * => * => & ordering
> fn borrow3<'a>(&'a self) -> &'a int {
> match (self) {
> // WORKS
> &Foo(ref v) => do_borrow(*v)
> }
> }
> }
The reason this works and borrow1 doesn't is a little tricky. As I
said above, the intermediate value has type ~int. The function
do_borrow takes something of type &int, so the compiler will coerce
the value of type ~int. The compiler silently does this so you don't
have to. This is equivalent to writing (as in this is what the
compiler automatically injects)
do_borrow(&**v)
> impl FooVec {
> fn borrow1<'a>(&'a self) -> &'a [int] {
> match (self) {
> // error: mismatched types: expected `&'a [int]` but found
> // `~[int]` ([] storage differs: expected &'a but found ~)
> &FooVec(ref v) => *v
> }
> }
This doesn't work due to the same reasons as the above borrow1
>
> fn borrow2<'a>(&'a self) -> &'a [int] {
> match (self) {
> // error: type ~[int] cannot be dereferenced
> &FooVec(ref v) => &**v
> }
> }
There's a subtle reason that this doesn't work. You'll note in the
above borrow2 I mentioned that you transformed ~int => int => &int. If
the same thing were to happen here, it would look like ~[int] => [int]
=> &[int]. This kind of promotion is not allowed yet (namely
dereferencing something of type ~[T]), but it will hopefully be
enabled soon with something called dynamically sized types (DST).
> fn borrow3<'a>(&'a self) -> &'a [int] {
> match (self) {
> // error: mismatched types: expected `&'a [int]` but found
> // `&<V2>` (expected vector but found &-ptr)
> &FooVec(ref v) => do_borrow(*v)
> }
> }
> }
This doesn't work because the do_borrow function takes something of
type &int, not ~[int] (which is the type of *v). You'd need to rewrite
the borrow function to take &[int] instead of &int.
Another solution for vectors is to return v.as_slice() which is a
function that will convert all forms of vectors to its slice
representation (&[T])
Hope that helps!
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev