【发布时间】:2021-03-07 03:54:06
【问题描述】:
我是rust 的新手,对函数调用感到震惊。
很抱歉,我无法制作干净的错误示例,因为iced::PickList 的构造函数中出现错误。
问题是——只要我在该调用中只使用一种方法——构建过程和程序就可以工作,但如果我只是将第二个需要的方法的签名更改为不是静态的——我就无法构建和修复 bowwor完全错误。
playground 上的完整工作(构建和启动)示例。
虽然看起来像这样,但通过Self::port_names() 调用,它可以工作。
extern crate iced;
extern crate midir;
use std::cell::RefCell;
use std::error::Error;
use std::io::{stdin, stdout, Write};
use std::option::Option::Some;
use std::sync::mpsc::{channel, Sender};
use iced::{
button, executor, pick_list, scrollable, Align, Application, Button, Column, Command,
Container, Element, Length, PickList, Scrollable, Settings, Space, Text,
};
use midir::{Ignore, MidiInput, MidiInputConnection, MidiInputPort, MidiInputPorts};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
struct Port {
pub index: usize,
}
struct BigNote {
note: i32,
need_init: bool,
client_name: String,
scroll: scrollable::State,
ports_list: pick_list::State<Port>,
selected_port: Port,
connection: Option<MidiInputConnection<Sender<Vec<u8>>>>,
}
impl BigNote {
fn midi_in(&self) -> MidiInput {
MidiInput::new(&self.client_name.to_string()).unwrap()
}
fn ports_names() -> Vec<Port> { // this is static method
let mut names: Vec<Port> = Vec::new();
names.push(Port { index: 0 });
names.push(Port { index: 1 });
names.into()
}
}
impl Application for BigNote {
type Executor = executor::Default;
type Message = Message;
type Flags = ();
fn new(_flags: ()) -> (BigNote, Command<self::Message>) {
(
BigNote {
note: -1,
need_init: true,
client_name: String::from("MyBigNote"),
connection: Option::None,
ports_list: pick_list::State::<Port>::default(),
scroll: scrollable::State::default(),
selected_port: Port { index: 1 },
},
Command::none(),
)
}
fn view(&mut self) -> Element<Message> {
let pick_list = PickList::new(
&mut self.ports_list,
Self::ports_names(), // here is static method
Some(self.selected_port.clone()),
Message::PortSelected,
);
let mut content = Scrollable::new(&mut self.scroll)
.width(Length::Fill)
.align_items(Align::Center)
.spacing(10)
.push(Space::with_height(Length::Units(600)))
.push(Text::new("Which is your favorite String?"))
.push(pick_list);
content = content.push(Space::with_height(Length::Units(600)));
Container::new(content)
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.center_y()
.into()
}
}
如果我只是替换方法签名——问题从«不可变借用不能与可变一起执行»开始,直到«临时资源不能从函数返回»。
extern crate iced;
extern crate midir;
use std::cell::RefCell;
use std::error::Error;
use std::io::{stdin, stdout, Write};
use std::option::Option::Some;
use std::sync::mpsc::{channel, Sender};
use iced::{
button, executor, pick_list, scrollable, Align, Application, Button, Column, Command,
Container, Element, Length, PickList, Scrollable, Settings, Space, Text,
};
use midir::{Ignore, MidiInput, MidiInputConnection, MidiInputPort, MidiInputPorts};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
struct Port {
pub index: usize,
}
struct BigNote {
note: i32,
need_init: bool,
client_name: String,
scroll: scrollable::State,
ports_list: pick_list::State<Port>,
selected_port: Port,
connection: Option<MidiInputConnection<Sender<Vec<u8>>>>,
}
impl BigNote {
fn midi_in(&self) -> MidiInput {
MidiInput::new(&self.client_name.to_string()).unwrap()
}
fn ports_names(&self) -> Vec<Port> { // here is change
let mut names: Vec<Port> = Vec::new();
names.push(Port { index: 0 });
names.push(Port { index: 1 });
names.into()
}
}
impl Application for BigNote {
type Executor = executor::Default;
type Message = Message;
type Flags = ();
fn new(_flags: ()) -> (BigNote, Command<self::Message>) {
(
BigNote {
note: -1,
need_init: true,
client_name: String::from("MyBigNote"),
connection: Option::None,
ports_list: pick_list::State::<Port>::default(),
scroll: scrollable::State::default(),
selected_port: Port { index: 1 },
},
Command::none(),
)
}
fn view(&mut self) -> Element<Message> {
let pick_list = PickList::new(
&mut self.ports_list,
self.ports_names(), // and here
Some(self.selected_port.clone()),
Message::PortSelected,
);
let mut content = Scrollable::new(&mut self.scroll)
.width(Length::Fill)
.align_items(Align::Center)
.spacing(10)
.push(Space::with_height(Length::Units(600)))
.push(Text::new("Which is your favorite String?"))
.push(pick_list);
content = content.push(Space::with_height(Length::Units(600)));
Container::new(content)
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.center_y()
.into()
}
}
请帮助我了解为什么会发生这种情况以及如何避免此类问题。
[编辑]
我觉得,我仍然没有得到 rust 中变量\局部变量的基本概念,就像我将 view 函数更改为这样:
fn view(&mut self) -> Element<Message> {
let port_names = self.ports_names(); // method call now here
let pick_list = PickList::new(
&mut self.ports_list,
port_names, // here only variable
Some(self.selected_port.clone()),
Message::PortSelected,
);
let mut content = Scrollable::new(&mut self.scroll)
.width(Length::Fill)
.align_items(Align::Center)
.spacing(10)
.push(Space::with_height(Length::Units(600)))
.push(Text::new("Which is your favorite String?"))
.push(pick_list);
content = content.push(Space::with_height(Length::Units(600)));
Container::new(content)
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.center_y()
.into()
}
成功了。 我知道原因是 - 我将直接方法调用移至本地可行,但我自己看不出有什么区别......
【问题讨论】:
标签: rust borrow-checker