I'm a newbie in rust, and stunned with making function call.
I'm sorry for I cannot make clean error example, as error occurs in the constructor of iced::PickList.
The matter is — as long as I use only one method in that call — the build pass and programm works, but if I just change the signature of the second needed method for be not static — I can not build and fix bowwor errors at all.
The complete working (builds and launches) example on the playground.
While it looks like this, with Self::port_names() call, it works.
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()
}
}
If I just replace the method signature — problems begin from «immutable borrow can not be performed along with mutable» until «temporary resource cannot be returned from function».
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()
}
}
Please, help me understand why is it happens and how to avoid such problems.
[EDIT]
I feel, I still don't get the fundamental concept of the variable\local variable in rust, as when i changed my view function to this:
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()
}
It worked. I understand that the reason is — I moved direct method call to the local viable, but I can see no difference here for myself...