Полагаю, я продублировал ваши настройки. Если что-то не так, пожалуйста, отредактируйте свой вопрос с соответствующими деталями.
src / main.rs:
use rppal::gpio::{Gpio, OutputPin, Pin};
struct Chip {
wake_pin: Option<OutputPin>,
}
impl Chip {
pub fn new(wake_pin: Option<Pin>) -> Chip {
Chip {
wake_pin: wake_pin.map(|pin| pin.into_output()),
}
}
pub fn awake(&self) {
// Fails
if let Some(pin) = self.wake_pin {
pin.set_low();
}
}
}
fn main() {
let wake_pin = Gpio::new()
.expect("Can not init gpio")
.get(255)
.expect("Could not attach to wake pin");
let chip = Chip::new(Some(wake_pin));
}
Cargo.toml:
[package]
name = "tmp"
version = "0.0.1"
edition = "2018"
[dependencies]
rppal = "0.11.3"
Пытаясь скомпилировать это (с cargo check
или аналогичным), мы получаем предупреждение и две ошибки.
warning: unused variable: `chip`
--> src/main.rs:28:9
|
28 | let chip = Chip::new(Some(wake_pin));
| ^^^^ help: consider prefixing with an underscore: `_chip`
|
= note: `#[warn(unused_variables)]` on by default
error[E0507]: cannot move out of `self.wake_pin.0` which is behind a shared reference
--> src/main.rs:16:28
|
16 | if let Some(pin) = self.wake_pin {
| --- ^^^^^^^^^^^^^ help: consider borrowing here: `&self.wake_pin`
| |
| data moved here
| move occurs because `pin` has type `rppal::gpio::pin::OutputPin`, which does not implement the `Copy` trait
error[E0596]: cannot borrow `pin` as mutable, as it is not declared as mutable
--> src/main.rs:17:13
|
16 | if let Some(pin) = self.wake_pin {
| --- help: consider changing this to be mutable: `mut pin`
17 | pin.set_low();
| ^^^ cannot borrow as mutable
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0507, E0596.
For more information about an error, try `rustc --explain E0507`.
error: Could not compile `tmp`.
To learn more, run the command again with --verbose.
Поскольку вы, вероятно, собираетесь использовать chip
позже, мыможно отключить предупреждение, временно переименовав его в _chip
.
let _chip = Chip::new(Some(wake_pin));
Первая ошибка говорит нам, что мы не можем вытащить пин-код из self
, поскольку мытолько заимствование self
. Было бы довольно грубо аннулировать данные за собой, если мы только заимствуем их. Тем не менее, компилятор говорит нам решение. help: consider borrowing here: `&self.wake_pin`
В конечном итоге это не совсем верно, но это правильное направление.
if let Some(pin) = &self.wake_pin {
pin.set_low();
}
Теперь вместо pin
с типом OutputPin
(собственное значение), этоимеет тип &OutputPin
(заимствованное значение).
Мы все еще получаем вторую ошибку, хотя (с немного другой формулировкой). Дело в том, что pin.set_low()
требует, чтобы pin
был изменяемой ссылкой. Прямо сейчас мы берем self
как неизменную ссылку (pub fn awake(&self)
). Если мы собираемся изменить self
или любое из его полей, мы должны принять его изменчиво. Это также означает, что мы должны быть уверены, что pin
заимствовано.
pub fn awake(&mut self) {
if let Some(pin) = &mut self.wake_pin {
pin.set_low();
}
}