Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allowing both static variables and boxes as a function argument?

Tags:

rust

I have a struct, which sometimes I instantiate statically, and sometimes I'd like users to allocate on the heap. Is it possible to allow both in as arguments to a function?

pub struct MyData {
    x: i32
}

static ALLOCATED_STATICALLY: MyData = MyData {x: 1};

// what should my signature be?
fn use_data(instance: Box<MyData>) {
    println!("{}", instance.x);
}

fn main () {
    use_data(Box::new(MyData{x: 2}));
    // this doesn't work currently
    use_data(ALLOCATED_STATICALLY);
}
like image 633
DrakeAnderson Avatar asked Oct 10 '15 07:10

DrakeAnderson


People also ask

Can a function be both static and const?

Since a static member method is not bound to an object there is no this -pointer to make const .

Can a static variable be passed to a function?

Yes, it's legal. Whether or not it's "correct", depends on what that function may do to the data. When you use a variable in a function call, you don't really pass the variable itself, only it's value. Or rather, a copy of its value.

Can you declare a variable is both static and extern?

It cannot be accessed from other module, even if they declare extern int i . People are using the keyword static (in this context) to keep i localize. Hence having i both declared as being defined somewhere else, AND defined as static within the module seems like an error.

How do you declare a static variable inside a function in Python?

Python doesn't have static variables but you can fake it by defining a callable class object and then using it as a function. Also see this answer. Note that __call__ makes an instance of a class (object) callable by its own name. That's why calling foo() above calls the class' __call__ method.


1 Answers

In both instances, you can pass a pointer to the function.

pub struct MyData {
    x: i32
}

static ALLOCATED_STATICALLY: MyData = MyData { x: 1 };

// what should my signature be?
fn use_data(instance: &MyData) {
    println!("{}", instance.x);
}

fn main () {
    use_data(&Box::new(MyData{ x: 2 }));
    use_data(&ALLOCATED_STATICALLY);
}

Note that in both cases, the caller needs to use the & operator to take the address of the value. In the first call, the operator yields a &Box<MyData>, but the compiler automatically converts it to a &MyData because Box implements the Deref trait.

like image 138
Francis Gagné Avatar answered Oct 04 '22 22:10

Francis Gagné