field is is interface that represents field of struct
struct Foo {
x: usize,
y: usize
}there's a field x, y in Foo so Foo::x and Foo::y is defined field
field can be accessed like this
fn field1() {
let foo = Foo {
x: 42,
y: 39,
};
assert_eq!(
foo.(Foo::x), //and the value of Foo::x can be accessed with Foo
foo.x //in short
);
}field can be field of field of field of .......
struct Bar {
foo: Foo,
}so Bar::foo.x and Bar::foo.y is field of Bar
fn field_of_field {
let bar = Bar {
foo: Foo {
x: 1,
y: 0
}
};
assert_eq!(1, bar.(Bar::foo.x));
assert_eq!(bar.(Bar::foo).x, bar.(Bar::foo.x));
assert_eq!(bar.foo.x, bar.(Bar::foo.x));
}borrows is a set of field to borrow
can be declared using borrows keyword
borrows can have public visibility
putting borrows in declaration of borrows will flatten it
so Foo::{ .. } and Foo::{ Foo::{ .. } } is same
pub borrows borrows1 = Foo::{
//you can put mutability
mut x,
y
}this will borrow x as immutable and others as mutable
pub borrows negative_borrow1 = Foo::{
x,
mut ..
}this will borrow others except x
pub borrows negative_borrow1 = Foo::{
!x,
..
}this will borrow foo.x
pub borrows borrow3 = Bar::{
foo.{
x
}
}in short
pub borrows borrow3 = Bar::{
foo.x
}//this will borrow Bar::foo with full mutability
pub borrows borrows2 = Bar::{
mut foo
}
//this will borrow Bar::foo as immutable and borrow Bar::foo.x as mutable
pub borrows borrow3 = Bar::{
foo.{
mut x,
..
}
}
//this will borrow Bar::foo as mutable except Bar::foo.x(immutable)
pub borrows borrow4 = Bar::{
foo.{
x,
mut ..
}
}
pub borrows borrow5 = Foo::{
mut x,
..
}
//this will borrow Bar::foo as immutable and borrow Bar::foo.x as mutable
pub borrows borrow6 = Bar::{
foo.{ borrow5 }
}borrows used in partial borrow
you don't need to do this as current borrow checker automatically implements partial borrow in this case
fn borrows_use() {
let foo = Foo {
x: 42,
y: 39
};
let foo_part1 = &foo.{ x }; //borrow only x
//using foo_part1.y will cause borrow check error
let foo_part2: &Foo::{ y } = &foo; //borrow only y
//using foo_part2.x will cause borrow check error
}impl Foo {
...this example makes private field Foo::x accessible out of the module with foo.x_another
field can have public visibility
field can be declared with field keyword
declared name should not conlfict with field name in Foo
...
pub field x_another = Self::x;
...you can borrow all fields of Foo like this
...
fn field2(&self.{ .. }) {
self.field3(); //you can borrow all fields of Foo so you can call field3
self.field4(); //you can borrow Foo::x so you can call field4
}
...borrowing all fields can be simplified
...
fn field3(&self) {
}
...borrow only Foo::x
...
fn field4(&self.{ x }) {
field6(self) //you can borrow Foo::x so you can call field6
}
...borrowing fields in typed param
...
fn field5(foo: &Foo::{ x }) {
//foo.field5() //you can't call field5 because you can't borrow { !x, .. } which is { Foo::y }
}
...borrow except Foo::x
...
fn field6(&self.{ !x, .. }) {
}
}trait Baz {
...you can declare field in trait block
it needs to be implemented when struct implements the trait
...
field baz_x: usize;
...borrow all fields of Self
...
fn field7(&self.{ .. }) -> usize {
self.baz_x //declared trait can be used here
}
...borrow all fields of Baz
so it's parital borrow
...
fn field8(&self.{ Bar::{ .. } }) -> usize{
self.baz_x
}
...you can declare borrows in trait block
like in this case, if you don't initialize it it will need to be implemented when implementing trait
...
borrows f: Self;
...you can add required borrows to Self::f when implementing Baz::field9
...
fn field9(&self.{ Self::f }) -> usize;
...you can borrowed `Self::f` so you can call field9
...
fn field10(&self.{ bar_x, Self::f }) {
self.field9();
}
......
fn field11(&self.{ Self::f }) -> usize;
}impl Baz for Foo {
...if Foo already has field with same name this can be accessed like foo.(Baz::field_name)
...
field baz_x: usize = Self::x;
...implementing borrows
...
borrows f = Self::{ y, x }
...Foo::f has Foo::y so you can access Foo::y
...
fn field9(&self.{ Self::f }) -> usize {
self.y //Foo::f has Foo::y so you can access Foo::y
}
...you can borrow less than declared in trait
...
fn field11(&self.{ y }) -> usize {
self.y
}
}fn field13() {
let foo = Foo {
x: 42,
y: 39,
};
assert_eq!(
foo.(Baz::bar_x),
foo.(Foo::bar_x)
);
assert_eq!(
foo.(Baz::bar_x),
foo.bar_x
);
assert_eq!(
foo.field8(),
foo.y
);
assert_eq!(
foo.field8(),
foo.field9()
);
}trait DerefField {
type FieldType;
field deref_field: Target;
}
impl<T: DerefField> Deref for DerefField {
type Target = Self::FieldType;
fn deref(&self { deref_field }) -> &Self::Target {
&self.deref_field
}
}
struct Example<T> {
value: T
}
impl<T> DerefField<T> for Example<T> {
field deref_field = self.value;
}