返回一个包含对将被丢弃的值的引用的结构体。

huangapple go评论69阅读模式
英文:

Return a struct which has a reference to a value which will be dropped

问题

I have problems with my code in rust. Ofc it has to to with borrowing. This is my first try at own code after reading the rust book.

The thing is, I kinda understand what the problem is and have an idea how to solve it, but that solution would end in some ugly structured code.

I have a struct which implements following method:

pub(crate) fn get_calendar_events(&self, name: &str) -> Result<Vec<Calendar>, String> {
    let xml: String = self.get_calendar_xml(name).map_err(|e| {
        format!("Error extracting xml: {}", e)
    })?;

    let event_responses: Vec<Responses> = self.parse_event_responses(&xml);

    let mut events: Vec<Calendar> = Vec::new();

    for response in event_responses {
        let ics_result: Result<Response, Error> = self.webdav_client.get(&format!("{}/{}", self.url, response.href));
        let ics_response: Response = ics_result.map_err(|e| {
            format!("Error in ics result: {}", e)
        })?;
        let mut ics: String = ics_response.text().map_err(|e| {
            format!("Error in ics response: {}", e)
        })?;

        let calendar_result: Result<Calendar<'_>, String> = read_calendar(&ics);

        let calendar_event: Calendar = calendar_result.map_err(|e| {
            format!("Error reading calendar event: {}", e)
        })?;
        events.push(calendar_event);
    }
    Ok(events)
}

Inside the loop I have the variable ics. The method read_calendar is from the crate "iCalendar" and takes a &str as argument. I want to unpack the result from read-calendar and push the calendar_event in a Vec which I want the method to return.

I get the error, that ics will be dropped at the end of the loop and calendar_result (and calendar_event) can't reference that value when it is dropped.

The only idea I have to solve this error is to outsource the complete loop to the place where I need access to the calendar_event, but this will end up in some chaotic looking code.

Coming from Java I probably approach things too much in that typical object-oriented way and have to try to rethink my approach.

英文:

I have problems with my code in rust. Ofc it has to to with borrowing. This is my first try at own code after reading the rust book.

The thing is, I kinda understand what the problem is and have an idea how to solve it, but that solution would end in some ugly structured code.

I have a struct which implements following method:

pub(crate) fn get_calendar_events(&amp;self, name: &amp;str) -&gt; Result&lt;Vec&lt;Calendar&gt;,String&gt; {
    let xml: String = self.get_calendar_xml(name).map_err(|e|{
        format!(&quot;Error extracting xml: {}&quot;, e)
    })?;

    let event_responses: Vec&lt;Responses&gt; = self.parse_event_responses(&amp;xml);

    let mut events: Vec&lt;Calendar&gt; = Vec::new();

    for response in event_responses {
        let ics_result: Result&lt;Response,Error&gt; = self.webdav_client.get(&amp;format!(&quot;{}/{}&quot;, self.url, response.href));
        let ics_response: Response = ics_result.map_err(|e|{
            format!(&quot;Error in ics result: {}&quot;, e)
        })?;
        let mut ics: String = ics_response.text().map_err(|e|{
            format!(&quot;Error in ics response: {}&quot;, e)
        })?;

        let calendar_result: Result&lt;Calendar&lt;&#39;_&gt;, String&gt; = read_calendar(&amp;ics);

        let calendar_event: Calendar = calendar_result.map_err(|e|{
            format!(&quot;Error reading calendar event: {}&quot;, e)
        })?;
        events.push(calendar_event);
    }
    Ok(events)
}

Inside the loop I have the variable ics . The method read_calendaris from the crate "iCalendar" and takes a &amp;str as argument. I want unpack the result from read-calendar and push the calendar_event in a Vec which I want the method to return.

I get the error, that ics will be dropped at the end of the loop and calendar_result (and calendar_event) can't reference that value when it is dropped.

The only idea I have to solve this error is to outsource the complete loop to the place where I need access to the calendar_event, but this will end up in some chaotic looking code.

Coming from java I probably approach things too much in that typical object-oriented way and have to try to rethink my approach.

答案1

得分: 4

似乎问题在于 Calendar 结构体不会拥有输入字符串,它只是保持了引用。

我对 icalendar 库不太熟悉,但看起来有两个不同的 Calendar 结构体:icalendar::parser::Calendar<'a>icalendar::Calendar

我在我的机器上进行了一些调整,删除了 webdav 部分,以便能够构建,但似乎使用 icalendar::Calendar 变体将会编译通过:

use icalendar::{parser::read_calendar, Calendar as CalendarOwned};

pub fn get_calendar_events(name: &str) -> Result<Vec<CalendarOwned>, String> {
    let mut events: Vec<CalendarOwned> = Vec::new();

    loop {
        let mut ics: String = "thing".to_owned();

        let calendar_result = read_calendar(&ics);

        let calendar_event = calendar_result
            .map_err(|e| format!("Error reading calendar event: {}", e))
            .unwrap();

        events.push(calendar_event.into());

        break;
    }

    Ok(events)
}

这个版本的结构体看起来大致相似,但拥有了其组成部分,而不是借用它们。不过,我对这个库不太熟悉,所以可能说得不准确。

英文:

It looks to me like the issue is that the Calendar struct doesn't take ownership of the input string, it just keeps the reference.

I'm not super familiar with the icalendar library, but it looks like there are two different Calendar structs: icalendar::parser::Calendar<'a>, and icalendar::Calendar.

I did some tweaking on my machine to remove the webdav stuff so it would build, but it seems that using the icalendar::Calendar variant will compile:

use icalendar::{parser::read_calendar, Calendar as CalendarOwned};

pub fn get_calendar_events(name: &amp;str) -&gt; Result&lt;Vec&lt;CalendarOwned&gt;, String&gt; {
    let mut events: Vec&lt;CalendarOwned&gt; = Vec::new();

    loop {
        let mut ics: String = &quot;thing&quot;.to_owned();

        let calendar_result = read_calendar(&amp;ics);

        let calendar_event = calendar_result
            .map_err(|e| format!(&quot;Error reading calendar event: {}&quot;, e))
            .unwrap();

        events.push(calendar_event.into());

        break;
    }

    Ok(events)
}

This version of the struct looks to be mostly similar, but taking ownership of its component parts instead of borrowing them. Like I say though, i'm not familliar with this library so I could be talking rubbish.

huangapple
  • 本文由 发表于 2023年6月11日 23:35:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76451198.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定