Давайте посмотрим, что такое Struct и как мы можем использовать его в языке Rust в этом разделе.

Примечание. Пожалуйста, ознакомьтесь с предыдущим разделом руководства, чтобы понять, что такое &str в rust.

Предыдущий раздел:https://medium.com/@manikandan96372/rust-for-beginners-part-8-str-6ce56c02ca88

Структура

Структура — это еще один тип в rust, который состоит из одного или нескольких типов или набора различных типов.

Если вы хотите описать только один атрибут, такой как имя, возраст или любой другой фактор, вы можете использовать такие типы, как строка, целое число и т. д., но что, если у вас есть сценарий, в котором атрибут, который вы хотите обсудить, требует более одного типа, например определение атрибуты человека или животного или чего-либо, что имеет несколько характеристик, которые нужно обсудить?

Тогда вашим помощником будет struct.

Рассмотрим сценарий описания автомобиля, в следующем фрагменте показано, как он должен быть определен с помощью структуры

fn main() {
  struct Car {
    brand: String,
    model: String,
    price: u64,
    mileage: u8
 }
}

Структура в rust создается с помощью ключевого слова struct, за которым следует имя структуры и набор фигурных скобок.

Внутри фигурных скобок вы можете создавать различные поля вашей структуры, используя различные типы в rust.

Выше мы добавляем поля, которые описывают автомобиль, используя строковый тип для марки автомобиля и названия модели, целое число без знака 64-битного типа для добавления поля цены и целое число без знака 8-битного типа для добавления поля пробега.

Похоже, вы уже видели это где-то, верно? Да, это может выглядеть как ваши классы и объекты на других языках программирования, таких как Javascript.

Давайте посмотрим, как мы можем создать экземпляр структуры

fn main() {
 struct Car {
    brand: String,
    model: String,
    price: u64,
    mileage: u8
 }
 let car = Car {
    brand: String::from("Toyota"),
    model: String::from("Corolla Altis"),
    price: 2000000,
    mileage: 20
  };
}

В приведенном выше примере имя переменной «car» содержит экземпляр структуры с определенным набором полей со значениями, определенными для нее, например «Toyota» как марка, 20 как пробег и т. д.

Примечание. Вы должны всегда определять каждое поле в своем элементе структуры, если вы пропустите какие-либо поля при его создании, ваш компилятор выдаст ошибку, говорящую о том, что у вас отсутствует поле в структуре.

Давайте посмотрим, как мы можем получить доступ к полям структуры.

В следующем фрагменте кода показано, как получить доступ к марке вашего автомобиля.

fn main() {
 struct Car {
    brand: String,
    model: String,
    price: u64,
    mileage: u8
 }
 let car = Car {
    brand: String::from("Toyota"),
    model: String::from("Corolla Altis"),
    price: 2000000,
    mileage: 20
  };
 println!("{}", car.brand);
}

Приведенный выше фрагмент кода при выполнении предоставит следующий вывод

Toyota

Для доступа к полям структуры вы должны указать имя переменной, за которым следует оператор точки (.), а затем имя вашего поля, вот как вы можете получить доступ к своим полям структуры.

Мы поняли, как создавать и получать доступ к переменным структуры, теперь давайте посмотрим, как мы можем реализовать методы для структуры, которые можно было бы использовать снаружи.

Внедрение

Impl — это ключевое слово, с помощью которого мы можем определить методы реализации для нашей структурной переменной.

Давайте рассмотрим сценарий, в котором мы хотим распечатать детали нашего автомобиля. Следующий фрагмент кода показывает, как этого добиться с помощью Impl

fn main() {
 struct Car {
    brand: String,
    model: String,
    price: u64,
    mileage: u8
 }
 impl Car {
   fn print_car_details(&self) {
     println!("{} {} {} {}", self.brand, self.model, self.price, self.mileage);
   }
 }
 let car = Car {
    brand: String::from("Toyota"),
    model: String::from("Corolla Altis"),
    price: 2000000,
    mileage: 20
  };
  car.print_car_details();
}

Приведенный выше фрагмент кода при выполнении даст следующий результат

Toyota Corolla Altis 2000000 20
  1. Если вы хотите внедрить методы в свою структурную переменную, используйте ключевое слово Impl, за которым следует имя вашей структуры, в данном случае это Car.
  2. Далее следует набор фигурных скобок, внутри которых вы можете определить свои методы, в данном случае это ваш «print_car_details».
  3. Здесь следует учитывать следующее: когда вы создаете экземпляр переменной структуры, вы определяете поля внутри нее, но как методы реализации вашей структуры узнают, какое поле структуры экземпляра следует напечатать?
  4. Вот почему «&self» передается в качестве аргумента вашему методу реализации.
  5. &self — это ссылкана экземпляр переменной структуры, с помощью которой вызываются методы реализации.
  6. Используя &self, методы реализации будут знать, из какого экземпляра следует обращаться к полям.
  7. При использовании метода реализации мы должны использовать структурную переменную «car», за которой следует оператор точки (.), а затем необходимый метод реализации, который здесь «print_car_details».

Вот как вы можете реализовать методы в своей структуре

Давайте посмотрим, как мы можем изменить поля структуры.

Наша ситуация такова, что мы должны реализовать новый метод, который добавляет 5 к существующему пробегу, когда мы вызываем этот метод, поле пробега вашего текущего экземпляра автомобиля должно иметь добавленное значение 5 к нему.

Следующий код показывает, как мы можем создать метод реализации change_mileage.

fn main() {
 struct Car {
    brand: String,
    model: String,
    price: u64,
    mileage: u8
  }
  impl Car {
    fn print_car_details(&self) {
      println!("{} {} {} {}", self.brand, self.model, self.price, self.mileage);
    }
    fn change_mileage(&self) {
      self.mileage = self.mileage + 5;
    }
  }
  let car = Car {
    brand: String::from("Toyota"),
    model: String::from("Corolla Altis"),
    price: 2000000,
    mileage: 20
   };
  car.change_mileage();
  car.print_car_details();
}

Приведенный выше фрагмент кода при выполнении выдаст следующую ошибку

В приведенной выше ошибке четко указано, что ссылка &self, которую вы передаете своему методу реализации, не является изменяемой ссылкой.

Таким образом, вы не можете изменить поле структуры, используя неизменяемую ссылку

Давайте изменим ссылку &self на изменяемую

fn main() {
 struct Car {
    brand: String,
    model: String,
    price: u64,
    mileage: u8
  }
 impl Car {
 fn print_car_details(&self) {
      println!("{} {} {} {}", self.brand, self.model, self.price, self.mileage);
    }
 fn change_mileage(&mut self) {
      self.mileage = self.mileage + 5;
    }
 }
 let car = Car {
    brand: String::from("Toyota"),
    model: String::from("Corolla Altis"),
    price: 2000000,
    mileage: 20
   };
 car.change_mileage();
 car.print_car_details();
}

Приведенный выше фрагмент кода при выполнении выдаст следующую ошибку

Но подождите, мы изменили наше &self на &mut self правильно, тогда почему это выдает ошибку?

Поскольку экземпляр автомобиля, который мы здесь создаем, не является изменяемым, поэтому мы должны изменить его также на изменяемый следующим образом.

fn main() {
  struct Car {
    brand: String,
    model: String,
    price: u64,
    mileage: u8
  }
 impl Car {
  fn print_car_details(&self) {
      println!("{} {} {} {}", self.brand, self.model, self.price, self.mileage);
    }
  fn change_mileage(&mut self) {
      self.mileage = self.mileage + 5;
    }
 }
 let mut car = Car {
    brand: String::from("Toyota"),
    model: String::from("Corolla Altis"),
    price: 2000000,
    mileage: 20
   };
 car.change_mileage();
 car.print_car_details();
}

Приведенный выше фрагмент кода при выполнении даст следующий результат

Toyota Corolla Altis 2000000 25

Теперь мы получаем измененный пробег (25 вместо 20) после вызова для него эквивалентного метода реализации.

Вот как мы можем использовать структуру в rust.

Давайте посмотрим, как мы можем использовать enum в rust в следующем разделе.