• Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Basic grammar

Continue to trait

  • We can also usetraitAdd member methods to other types
    • The following code,i32We didn’t write it at all
    • But we can givei32Increase method

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



impl Double for i32 {
    fn double(&self) - >i32{*self * 2}}fn main() {
    let x : i32 = 10.double();
    // Outputs the value of type double as 20
    println!("Values of type double are {}",x)
}
Copy the code

Generic function call syntax


trait Cook {
    fn start(&self);
}


trait Wash {
    fn start(&self);
}

struct Chef;

impl Cook for Chef {
    fn start(&self) {
        println!("Start cooking!!"); }}impl Wash for Chef {
    fn start(&self) {
        println!("Wash the dishes!!"); }}fn main() {
    let me = Chef;
    / / output
    // Start cooking!
    // Start washing dishes!!
    <Cook>::start(&me);
    <Chef as Wash>::start(&me);
}
Copy the code
  • The above code is inmainIn, write two specificallytraitTo call
    • Because if you just write one sentenceme.start()Ambiguity arises
    • So you have to be careful when you call it, you have to be careful which one it istrait

The generic


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']);
}
Copy the code
  • Above code, in which{:? }Is the formatting control character

An array of


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
    for i in b {
        print!("{}",i); }}Copy the code
  • Above code: pay attention to array length, array type
    • An array ofbIt’s ten0

Array slice

  • We can think of an array slice as a pointer to an array
    • You can view it as one of the arraysview
    • The array in this example is[T; n]The type of
    • The pointer type is&[T; n]To convert an array type to a slice type by internal compilation&[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);
    }
    // The output is:
    // size of &[i32; 3] : 8
    // size of &[i32] : 16
    / / [1, 2, 5]
    println!("{:? }",v);
}
Copy the code
  • The above code contains variablesvis[i32; 3]type
    • variablesis&mut [i32; 3]Type, which takes up the same amount of space as the pointer
    • When automatically converted&mut [i32; 3]Type, passing in a functionmut_arr
    • Based on the output, you can see that the space occupied is equal to the space occupied by two Pointers
    • Inside the function, the value of v for the external array is changed

Fat pointer andDST

  • Array slicing contains not only Pointers to arrays, but also lengths of informationFat pointer
    • Fat paper corresponds to dynamic size type, or DST for short

    • For example, we use an indeterminate array of type [T] and the corresponding fat pointer of type &[T].

    • It is impossible to determine the size of the space occupied by the type

    • So you can’t declare an instance of a variable on the stack that doesn’t grow

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);
    // The output is:
    // Address of arr is: 0x7ffee759f424
    // Value1 is 7ffee759f424
    // Value2 is 5
    example_slice(addr as& [i32]);
}
Copy the code
  • In the code above,arrIs the length of the5
    • Among themaddrIs pointing toarrA pointer to
    • Use the function to convert our array directly to a length and an address pointing to the source array

Range

  • RangeRepresents an interval
    • use.Represents the left open and right closed interval
    • Such as1.. 7It stands for 1 to 7
fn main() {

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