Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to return either a borrowed or owned type in Rust?

Tags:

rust

ownership

In the following code, how can I return the reference of floor instead of a new object? Is it possible to let the function return either a borrowed reference or an owned value?

extern crate num; // 0.2.0

use num::bigint::BigInt;

fn cal(a: BigInt, b: BigInt, floor: &BigInt) -> BigInt {
    let c: BigInt = a - b;
    if c.ge(floor) {
        c
    } else {
        floor.clone()
    }
}
like image 866
lucian Avatar asked Apr 19 '16 00:04

lucian


People also ask

What is an owned type Rust?

When we talk about ownership in Rust, we generally mean – a variable owns a value. As we assign the same value between variables, we move the value, changing the owner. While this is true for Rust Owned types, the behavior is different for Rust References (also known as Borrowed types).

Can Rust be borrowed?

The ownership rules dictate how Rust manages memory over the stack and heap. As you write Rust programs, you'll need to use variables without changing the ownership of the associated value. Rust provides a robust borrowing mechanism to encourage flexibility and code reuse.


1 Answers

Since BigInt implements Clone, you can use a std::borrow::Cow:

use num::bigint::BigInt; // 0.2.0
use std::borrow::Cow;

fn cal(a: BigInt, b: BigInt, floor: &BigInt) -> Cow<BigInt> {
    let c: BigInt = a - b;
    if c.ge(floor) {
        Cow::Owned(c)
    } else {
        Cow::Borrowed(floor)
    }
}

Later, you can use Cow::into_owned() to get a owned version of BigInt, or just use it as a reference:

fn main() {
    let a = BigInt::from(1);
    let b = BigInt::from(2);
    let c = &BigInt::from(3);

    let result = cal(a, b, c);

    let ref_result = &result;
    println!("ref result: {}", ref_result);

    let owned_result = result.into_owned();
    println!("owned result: {}", owned_result);
}
like image 145
WiSaGaN Avatar answered Sep 21 '22 13:09

WiSaGaN