Ржавчина начинается с 0️⃣ (3)

задняя часть Rust
Ржавчина начинается с 0️⃣ (3)

Базовая грамматика

продолжить черту

  • мы также можем использоватьtraitДобавьте методы-члены к другим типам
    • Следующий код,i32вовсе не нами написано
    • Но мы можем датьi32метод увеличения

trait Double {
    fn double(&self) -> Self;
}



impl Double for i32 {
    fn double(&self) -> i32 {
        *self * 2
    }
}


fn main() {
    let x : i32 = 10.double();
    //输出 double类型的值为 20
    println!("double类型的值为 {}",x)
}

Общий синтаксис вызова функции


trait Cook {
    fn start(&self);
}


trait Wash {
    fn start(&self);
}

struct Chef;

impl Cook for Chef {
    fn start(&self) {
        println!("开始烹饪!!");
    }
}

impl Wash for Chef {
    fn start(&self) {
        println!("开始刷碗!!");
    }
}



fn main() {
    let me = Chef;
    //输出 
    // 开始烹饪!!
    // 开始刷碗!!
    <Cook>::start(&me);
    <Chef as Wash>::start(&me);
}
  • Приведенный выше кодmain, специально написано для двухtraitзвонить
    • Потому что, если вы напишете только одно предложениеme.start()двусмысленность
    • Так что при звонке надо обращать внимание на то, какому из них вы должны соответствовать.trait

Дженерики


fn test<T : Debug>(x : T) {
   println!("this is {:?}.",x);
}


fn main() {
   /*
   this is "Test".
   this is 77.
   this is true.
   this is ['n', 'a', 's', 's'].
   */
   test("Test");
   test(77i32);
   test(true);
   test(['n','a','s','s']);
}
  • Приведенный выше код, где{:?}управление форматом

множество


fn main() {

    let a: [i32; 3] = [1,2,3];
    let b: [i32; 10] = [0; 10];

    //1 2 3
    for i in a {
        print!(" {}",i);
    }
    // 0 0 0 0 0 0 0 0 0 0
    for i in b {
        print!(" {}",i);
    }
}
  • Приведенный выше код: обратите внимание на длину массива и тип массива
    • множествоbназначается десять0

срез массива

  • Мы можем думать о срезах массива как о специализированных указателях на массивы.
    • Можно понимать как один из массивов视图
    • Массив в примере[T; n]Тип
    • тип указателя&[T; n], который преобразует тип массива в тип среза путем внутренней компиляции.&[T]
fn main() {

    fn mut_arr(a : &mut [i32]) {
        a[2] = 5;
    }

    println!("size of &[i32; 3] : {:?}", std::mem::size_of::<&[i32; 3]>());
    println!("size of &[i32]  : {:?}", std::mem::size_of::<&[i32]>());

    let mut v : [i32; 3] = [1,2,3];
    {
        let s : &mut [i32; 3] = &mut v;
        mut_arr(s);
    }
    // 输出为:
    // size of &[i32; 3] : 8
    // size of &[i32]  : 16
    // [1, 2, 5]
    println!("{:?}",v);
}
  • Приведенный выше код содержит переменныеvда[i32; 3]Типы
    • Переменнаяsда&mut [i32; 3]Тип, занимающий столько же места, сколько и указатель
    • при автоматическом преобразовании в&mut [i32; 3]введите, передайте в функциюmut_arr
    • Согласно выводу видно, что занимаемое пространство равно размеру пространства двух указателей.
    • Внутри функции изменяется значение v внешнего массива.

толстый указатель сDST

  • Поскольку срезы массива содержат не только указатели на массивы, сами срезы также содержат информацию о длине, поэтому он называется胖指针
    • Жирная бумага действительно соответствует动态大小类型сокращенныйDST

    • Например, тип массива переменной длины, используемый в примере, имеет вид[T], соответствующий толстый тип указателя&[T]

    • Потому что размер пространства, занимаемого типом, не может быть определен

    • Таким образом, вы не можете объявить экземпляр переменной массива неопределенного размера в стеке

fn example_slice(arr: &[i32]) {
    unsafe {
        let (v1, v2) : (usize,usize) = std::mem::transmute(arr);

        println!("Value1 is {:x}",v1);
        println!("Value2 is {:x}",v2);
    }
}

fn main() {

    let arr : [i32; 5] = [1,2,3,4,5];
    let addr : &[i32; 5] = &arr;
    println!("Address of arr is: {:p}",addr);
    // 输出为:
    // Address of arr is: 0x7ffee759f424
    // Value1 is 7ffee759f424
    // Value2 is 5
    example_slice(addr as &[i32]);
}
  • В приведенном выше кодеarrДлина5
    • вaddrуказывает наarrуказатель на
    • Используйте функцию для преобразования нашего массива непосредственно вдлинас однимадрес к исходному массиву

Range

  • Rangeпредставляет диапазон
    • использовать..Представляет интервал, открытый слева и закрытый справа
    • подобно1..7означает от 1 до 7
fn main() {

    let a = 1..7;
    
    // 1   2  3  4  5  6
    for i in a {
        print!("{:?}\t",i);
    }
}