Some syntax issues: ' and self.0 and (**self)

when i read source code,there are some syntax issues confuse me.
(1)

impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for &'cs mut CS 

"cs" should be a variable name,what does it mean to add symbol ' in front of it?

(2)

fn enforce<A, AR, LA, LB, LC>(
        &mut self,
        annotation: A,
        a: LA,
        b: LB,
        c: LC
    )
        where A: FnOnce() -> AR, AR: Into<String>,
              LA: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
              LB: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
              LC: FnOnce(LinearCombination<E>) -> LinearCombination<E>
    {
        self.0.enforce(annotation, a, b, c)
    }

The above code is a function implementation in an impl block of trait, what is the syntax of self.0.enforce?

(3)

fn enforce<A, AR, LA, LB, LC>(
        &mut self,
        annotation: A,
        a: LA,
        b: LB,
        c: LC
    )
        where A: FnOnce() -> AR, AR: Into<String>,
              LA: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
              LB: FnOnce(LinearCombination<E>) -> LinearCombination<E>,
              LC: FnOnce(LinearCombination<E>) -> LinearCombination<E>
    {
        (**self).enforce(annotation, a, b, c)
    }

The code here is another impl of the trait in (2). What syntax is used here for (**self).enforce?

To the first, 'ident is an explicit lifetime annotation. In impl<'a> Trait for &'a Type, this is saying that we're implementing Trait for &Type for any lifetime. Alternatively, we could say impl Trait for &'static Type, and Trait is only provided for references with the 'static lifetime (that are valid for the entire rest of the program execution).

To the latter, self is a special identifier for the receiver type for methods, like this in most Object Oriented languages.

When you write fn foo(&self), this is essentially sugar for the expanded form fn foo(self: &Self). When we later call the method as object.foo(), object is passed to the function as the self argument.

self.0.enforce( is thus accessing the .0 member of the self argument (the Self type is either a tuple or a tuple struct) and calling the enforce method on it. (**self).enforce is dereferencing the self argument twice and then calling the enforce method; the double dereference is because self is here a &mut Self variable, so the first dereference removes the &mut and the second dereferences the Self. In this case, Self is probably itself a mutable reference, and the impl is probably to forward the implementation of Trait for &mut T to the Trait impl for T.

1 Like

ok,i should keep reading the book.Thanks

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.